Title: [262456] trunk
Revision
262456
Author
peng.l...@apple.com
Date
2020-06-02 15:26:02 -0700 (Tue, 02 Jun 2020)

Log Message

Stressing webkitSetPresentationMode leads to wrong inline video dimensions
https://bugs.webkit.org/show_bug.cgi?id=202425

Reviewed by Eric Carlson.

Source/WebCore:

Make the HTMLVideoElement::setFullscreenMode() robust under stress tests
by ignoring a request when the video element is not ready yet.

Manually tested.

* dom/Element.h:
(WebCore::Element::didStopBeingFullscreenElement):
Add a callback to indicate that the element has exited fullscreen.
* dom/FullscreenManager.cpp:
(WebCore::FullscreenManager::didExitFullscreen):
Call Element::didStopBeingFullscreenElement() when the element has exited fullscreen.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::enterFullscreen):
* html/HTMLMediaElement.h:

* html/HTMLVideoElement.cpp:
(WebCore::HTMLVideoElement::webkitDisplayingFullscreen):
This function will return true when a video element is in the process to exit
fullscreen/picture-in-picture until it has completed the process. Therefore, a page
can safely request the video element to enter fullscreen/picture-in-picture when
this function returns false.

(WebCore::HTMLVideoElement::setFullscreenMode):
(WebCore::HTMLVideoElement::didBecomeFullscreenElement):
(WebCore::HTMLVideoElement::didStopBeingFullscreenElement):
(WebCore::HTMLVideoElement::didEnterFullscreen): Deleted.
(WebCore::HTMLVideoElement::didExitFullscreen): Deleted.
* html/HTMLVideoElement.h:
Add a flag m_isChangingPresentationMode. webkitSetPresentationMode() will only
change the presentation mode when the flag is false.

Source/WebKit:

* WebProcess/cocoa/VideoFullscreenManager.mm:
(WebKit::VideoFullscreenManager::didEnterFullscreen):
(WebKit::VideoFullscreenManager::didCleanupFullscreen):

Source/WebKitLegacy/mac:

Move DumpRenderTree's implementation of the mock video presentation mode from WebView
to WebChromeClient and call videoElement.didStopBeingFullscreenElement() when a video
element exits fullscreen.

* WebCoreSupport/WebChromeClient.h:
* WebCoreSupport/WebChromeClient.mm:
(WebChromeClient::setMockVideoPresentationModeEnabled):
(WebChromeClient::enterVideoFullscreenForVideoElement):
(WebChromeClient::exitVideoFullscreenForVideoElement):
(WebChromeClient::exitVideoFullscreenToModeWithoutAnimation):
* WebView/WebView.mm:
(-[WebView _enterVideoFullscreenForVideoElement:mode:]):
(-[WebView _exitVideoFullscreen]):
(-[WebView _setMockVideoPresentationModeEnabled:]): Deleted.
* WebView/WebViewData.h:
* WebView/WebViewInternal.h:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/WKWebViewCloseAllMediaPresentations.mm:
(TEST):

LayoutTests:

Enable the mock video presentation mode in WebKitTestRunner and
only request a video element to enter/exit fullscreen/picture-in-picture when
the element is ready to do so (by checking the attribute webkitDisplayingFullscreen).

* media/modern-media-controls/placard-support/placard-support-pip-expected.txt:
* media/modern-media-controls/placard-support/placard-support-pip.html:
* media/presentationmodechanged-fired-once-expected.txt:
* media/presentationmodechanged-fired-once.html:
* media/video-presentation-mode-expected.txt:
* media/video-presentation-mode.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (262455 => 262456)


--- trunk/LayoutTests/ChangeLog	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/LayoutTests/ChangeLog	2020-06-02 22:26:02 UTC (rev 262456)
@@ -1,3 +1,21 @@
+2020-06-02  Peng Liu  <peng.l...@apple.com>
+
+        Stressing webkitSetPresentationMode leads to wrong inline video dimensions
+        https://bugs.webkit.org/show_bug.cgi?id=202425
+
+        Reviewed by Eric Carlson.
+
+        Enable the mock video presentation mode in WebKitTestRunner and
+        only request a video element to enter/exit fullscreen/picture-in-picture when
+        the element is ready to do so (by checking the attribute webkitDisplayingFullscreen).
+
+        * media/modern-media-controls/placard-support/placard-support-pip-expected.txt:
+        * media/modern-media-controls/placard-support/placard-support-pip.html:
+        * media/presentationmodechanged-fired-once-expected.txt:
+        * media/presentationmodechanged-fired-once.html:
+        * media/video-presentation-mode-expected.txt:
+        * media/video-presentation-mode.html:
+
 2020-06-02  Simon Fraser  <simon.fra...@apple.com>
 
         [ macOS ] scrollingcoordinator/mac/latching/horizontal-overflow-back-swipe.html is flaky timing out

Modified: trunk/LayoutTests/media/modern-media-controls/placard-support/placard-support-pip-expected.txt (262455 => 262456)


--- trunk/LayoutTests/media/modern-media-controls/placard-support/placard-support-pip-expected.txt	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/LayoutTests/media/modern-media-controls/placard-support/placard-support-pip-expected.txt	2020-06-02 22:26:02 UTC (rev 262456)
@@ -3,8 +3,10 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
+PASS media.webkitDisplayingFullscreen became true
 PASS mediaController.controls.placard is mediaController.controls.pipPlacard
 PASS mediaController.controls.children.includes(mediaController.controls.pipPlacard) is true
+PASS media.webkitDisplayingFullscreen became false
 PASS mediaController.controls.placard is null
 PASS mediaController.controls.children.includes(mediaController.controls.pipPlacard) is false
 PASS successfullyParsed is true

Modified: trunk/LayoutTests/media/modern-media-controls/placard-support/placard-support-pip.html (262455 => 262456)


--- trunk/LayoutTests/media/modern-media-controls/placard-support/placard-support-pip.html	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/LayoutTests/media/modern-media-controls/placard-support/placard-support-pip.html	2020-06-02 22:26:02 UTC (rev 262456)
@@ -25,8 +25,10 @@
 
 description("Testing the <code>PlacardSupport</code> behavior when entering picture-in-picture.");
 
-if (window.internals)
+if (window.internals) {
     window.internals.settings.setAllowsPictureInPictureMediaPlayback(true);
+    window.internals.setMockVideoPresentationModeEnabled(true);
+}
 
 const container = document.querySelector("div#host");
 const media = document.querySelector("video");
@@ -36,19 +38,22 @@
 button.innerText = "Enter picture-in-picture";
 
 button.addEventListener("click", togglePiP);
-
 media.addEventListener("webkitpresentationmodechanged", () => {
     if (media.webkitPresentationMode == "picture-in-picture") {
-        shouldBe("mediaController.controls.placard", "mediaController.controls.pipPlacard");
-        shouldBeTrue("mediaController.controls.children.includes(mediaController.controls.pipPlacard)");
-        togglePiP();
+        shouldBecomeEqual("media.webkitDisplayingFullscreen", "true", () => {
+            shouldBe("mediaController.controls.placard", "mediaController.controls.pipPlacard");
+            shouldBeTrue("mediaController.controls.children.includes(mediaController.controls.pipPlacard)");
+            togglePiP();
+        });
     } else {
-        shouldBeNull("mediaController.controls.placard");
-        shouldBeFalse("mediaController.controls.children.includes(mediaController.controls.pipPlacard)");
-        container.remove();
-        media.remove();
-        button.remove();
-        finishJSTest();
+        shouldBecomeEqual("media.webkitDisplayingFullscreen", "false", () => {
+            shouldBeNull("mediaController.controls.placard");
+            shouldBeFalse("mediaController.controls.children.includes(mediaController.controls.pipPlacard)");
+            container.remove();
+            media.remove();
+            button.remove();
+            finishJSTest();
+        });
     }
 });
 

Modified: trunk/LayoutTests/media/presentationmodechanged-fired-once-expected.txt (262455 => 262456)


--- trunk/LayoutTests/media/presentationmodechanged-fired-once-expected.txt	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/LayoutTests/media/presentationmodechanged-fired-once-expected.txt	2020-06-02 22:26:02 UTC (rev 262456)
@@ -1,11 +1,11 @@
 This tests that the "webkitpresentationmodechanged" event is fired only once when the browser switches back to inline from the picture-in-picture mode.
 
-RUN(internals.settings.setAllowsPictureInPictureMediaPlayback(true))
 RUN(video.src = "" "content/test"))
 EVENT(canplaythrough)
 RUN(video.play())
 RUN(video.webkitSetPresentationMode("picture-in-picture"))
 EVENT(webkitpresentationmodechanged)
+EXPECTED (video.webkitDisplayingFullscreen == 'true') OK
 EXPECTED (video.webkitPresentationMode == 'picture-in-picture') OK
 RUN(video.webkitSetPresentationMode("inline"))
 EVENT(webkitpresentationmodechanged)

Modified: trunk/LayoutTests/media/presentationmodechanged-fired-once.html (262455 => 262456)


--- trunk/LayoutTests/media/presentationmodechanged-fired-once.html	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/LayoutTests/media/presentationmodechanged-fired-once.html	2020-06-02 22:26:02 UTC (rev 262456)
@@ -8,8 +8,12 @@
 
         function go()
         {
+            if (window.internals) {
+                internals.settings.setAllowsPictureInPictureMediaPlayback(true);
+                internals.setMockVideoPresentationModeEnabled(true);
+            }
+
             findMediaElement();
-            run('internals.settings.setAllowsPictureInPictureMediaPlayback(true)');
             run('video.src = "" "content/test")');
             waitForEventOnce('canplaythrough', canPlayThrough);
         }
@@ -21,8 +25,9 @@
             waitForEventOnce("webkitpresentationmodechanged", presentationModeChanged1);
         }
 
-        function presentationModeChanged1()
+        async function presentationModeChanged1()
         {
+            await testExpectedEventually('video.webkitDisplayingFullscreen', true);
             testExpected("video.webkitPresentationMode", "picture-in-picture");
             runWithKeyDown('video.webkitSetPresentationMode("inline")');
             waitForEvent("webkitpresentationmodechanged", presentationModeChanged2);

Modified: trunk/LayoutTests/media/video-presentation-mode-expected.txt (262455 => 262456)


--- trunk/LayoutTests/media/video-presentation-mode-expected.txt	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/LayoutTests/media/video-presentation-mode-expected.txt	2020-06-02 22:26:02 UTC (rev 262456)
@@ -9,6 +9,7 @@
 ** Try to enter fullscreen
 RUN(video.webkitSetPresentationMode('fullscreen'))
 EVENT(webkitpresentationmodechanged)
+EXPECTED (video.webkitDisplayingFullscreen == 'true') OK
 
 ** Entered fullscreen
 EXPECTED (video.webkitPresentationMode == 'fullscreen') OK
@@ -16,6 +17,7 @@
 ** Try to enter picture-in-picture
 RUN(video.webkitSetPresentationMode('picture-in-picture'))
 EVENT(webkitpresentationmodechanged)
+EXPECTED (video.webkitDisplayingFullscreen == 'true') OK
 
 ** Entered picture-in-picture
 EXPECTED (video.webkitPresentationMode == 'picture-in-picture') OK
@@ -23,6 +25,7 @@
 ** Try to return to inline
 RUN(video.webkitSetPresentationMode('inline'))
 EVENT(webkitpresentationmodechanged)
+EXPECTED (video.webkitDisplayingFullscreen == 'false') OK
 
 ** Returned to inline
 EXPECTED (video.webkitPresentationMode == 'inline') OK

Modified: trunk/LayoutTests/media/video-presentation-mode.html (262455 => 262456)


--- trunk/LayoutTests/media/video-presentation-mode.html	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/LayoutTests/media/video-presentation-mode.html	2020-06-02 22:26:02 UTC (rev 262456)
@@ -1,63 +1,66 @@
 <!doctype html>
 <html>
     <head>
-	    <script src=""
-	    <script src=""
-	    <script>
+        <script src=""
+        <script src=""
+        <script>
             function start()
             {
-	            if (window.internals) {
-                    window.internals.settings.setAllowsPictureInPictureMediaPlayback(true);
-                    window.internals.setMockVideoPresentationModeEnabled(true);
+                if (window.internals) {
+                    internals.settings.setAllowsPictureInPictureMediaPlayback(true);
+                    internals.setMockVideoPresentationModeEnabled(true);
                 }
-	
-	            video = document.getElementsByTagName('video')[0];
-	            waitForEventOnce("canplaythrough", canplaythrough);
-	            video.src = "" "content/test");
 
-	            consoleWrite("");
+                video = document.getElementsByTagName('video')[0];
+                waitForEventOnce("canplaythrough", canplaythrough);
+                video.src = "" "content/test");
+
+                consoleWrite("");
             }
-	
-	        function canplaythrough()
-	        {
-	            testExpected("video.webkitSupportsFullscreen", true);
-	            testExpected("video.webkitDisplayingFullscreen", false);
-	
-	            consoleWrite("<br>** Try to enter fullscreen");
-	            runWithKeyDown("video.webkitSetPresentationMode('fullscreen')");
-	            waitForEventOnce('webkitpresentationmodechanged', presentationModeChanged1);
-	        }
-	
-	        function presentationModeChanged1()
-	        {
-	            consoleWrite("<br>** Entered fullscreen");
-	            testExpected("video.webkitPresentationMode", "fullscreen");
-	            consoleWrite("<br>** Try to enter picture-in-picture");
-	            waitForEventOnce('webkitpresentationmodechanged', presentationModeChanged2);
-	            runWithKeyDown("video.webkitSetPresentationMode('picture-in-picture')");
-	        }
-	
-	        function presentationModeChanged2()
-	        {
-	            consoleWrite("<br>** Entered picture-in-picture");
-	            testExpected("video.webkitPresentationMode", "picture-in-picture");
-	            consoleWrite("<br>** Try to return to inline");
-	            waitForEventOnce('webkitpresentationmodechanged', testCompleted);
-	            runWithKeyDown("video.webkitSetPresentationMode('inline')");
-	        }
-	
-	        function testCompleted()
-	        {
-	            consoleWrite("<br>** Returned to inline");
-	            testExpected("video.webkitPresentationMode", "inline");
-	            consoleWrite("<br>** Test Completed");
-	            endTest();
-	        }
-	    </script>
-	</head>
-	
-	<body _onload_="start()">
-	    <video controls playsinline></video>
-	    <p>Test the video presentation mode (video fullscreen and picture-in-picture) API.</p>
-	</body>
+
+            async function canplaythrough()
+            {
+                testExpected("video.webkitSupportsFullscreen", true);
+                await testExpectedEventually('video.webkitDisplayingFullscreen', false);
+
+                consoleWrite("<br>** Try to enter fullscreen");
+                runWithKeyDown("video.webkitSetPresentationMode('fullscreen')");
+                waitForEventOnce('webkitpresentationmodechanged', presentationModeChanged1);
+            }
+
+            async function presentationModeChanged1()
+            {
+                await testExpectedEventually('video.webkitDisplayingFullscreen', true);
+                consoleWrite("<br>** Entered fullscreen");
+                testExpected("video.webkitPresentationMode", "fullscreen");
+                consoleWrite("<br>** Try to enter picture-in-picture");
+                waitForEventOnce('webkitpresentationmodechanged', presentationModeChanged2);
+                runWithKeyDown("video.webkitSetPresentationMode('picture-in-picture')");
+            }
+
+            async function presentationModeChanged2()
+            {
+                await testExpectedEventually('video.webkitDisplayingFullscreen', true);
+                consoleWrite("<br>** Entered picture-in-picture");
+                testExpected("video.webkitPresentationMode", "picture-in-picture");
+                consoleWrite("<br>** Try to return to inline");
+                waitForEventOnce('webkitpresentationmodechanged', testCompleted);
+                runWithKeyDown("video.webkitSetPresentationMode('inline')");
+            }
+
+            async function testCompleted()
+            {
+                await testExpectedEventually('video.webkitDisplayingFullscreen', false);
+                consoleWrite("<br>** Returned to inline");
+                testExpected("video.webkitPresentationMode", "inline");
+                consoleWrite("<br>** Test Completed");
+                endTest();
+            }
+        </script>
+    </head>
+
+    <body _onload_="start()">
+        <video controls playsinline></video>
+        <p>Test the video presentation mode (video fullscreen and picture-in-picture) API.</p>
+    </body>
 </html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (262455 => 262456)


--- trunk/Source/WebCore/ChangeLog	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebCore/ChangeLog	2020-06-02 22:26:02 UTC (rev 262456)
@@ -1,3 +1,42 @@
+2020-06-02  Peng Liu  <peng.l...@apple.com>
+
+        Stressing webkitSetPresentationMode leads to wrong inline video dimensions
+        https://bugs.webkit.org/show_bug.cgi?id=202425
+
+        Reviewed by Eric Carlson.
+
+        Make the HTMLVideoElement::setFullscreenMode() robust under stress tests
+        by ignoring a request when the video element is not ready yet.
+
+        Manually tested.
+
+        * dom/Element.h:
+        (WebCore::Element::didStopBeingFullscreenElement):
+        Add a callback to indicate that the element has exited fullscreen.
+        * dom/FullscreenManager.cpp:
+        (WebCore::FullscreenManager::didExitFullscreen):
+        Call Element::didStopBeingFullscreenElement() when the element has exited fullscreen.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::enterFullscreen):
+        * html/HTMLMediaElement.h:
+
+        * html/HTMLVideoElement.cpp:
+        (WebCore::HTMLVideoElement::webkitDisplayingFullscreen):
+        This function will return true when a video element is in the process to exit
+        fullscreen/picture-in-picture until it has completed the process. Therefore, a page
+        can safely request the video element to enter fullscreen/picture-in-picture when
+        this function returns false.
+
+        (WebCore::HTMLVideoElement::setFullscreenMode):
+        (WebCore::HTMLVideoElement::didBecomeFullscreenElement):
+        (WebCore::HTMLVideoElement::didStopBeingFullscreenElement):
+        (WebCore::HTMLVideoElement::didEnterFullscreen): Deleted.
+        (WebCore::HTMLVideoElement::didExitFullscreen): Deleted.
+        * html/HTMLVideoElement.h:
+        Add a flag m_isChangingPresentationMode. webkitSetPresentationMode() will only
+        change the presentation mode when the flag is false.
+
 2020-06-01  Simon Fraser  <simon.fra...@apple.com>
 
         Add ENABLE(WHEEL_EVENT_REGIONS), enabled on macOS which is the only platform that needs wheel event regions for scrolling thread hit-testing

Modified: trunk/Source/WebCore/dom/Element.h (262455 => 262456)


--- trunk/Source/WebCore/dom/Element.h	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebCore/dom/Element.h	2020-06-02 22:26:02 UTC (rev 262456)
@@ -423,6 +423,7 @@
     virtual void ancestorWillEnterFullscreen() { }
     virtual void didBecomeFullscreenElement() { }
     virtual void willStopBeingFullscreenElement() { }
+    virtual void didStopBeingFullscreenElement() { }
 
     bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); }
     void finishParsingChildren() override;

Modified: trunk/Source/WebCore/dom/FullscreenManager.cpp (262455 => 262456)


--- trunk/Source/WebCore/dom/FullscreenManager.cpp	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebCore/dom/FullscreenManager.cpp	2020-06-02 22:26:02 UTC (rev 262456)
@@ -421,6 +421,7 @@
     if (!hasLivingRenderTree() || backForwardCacheState() != Document::NotInBackForwardCache)
         return;
     fullscreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(false);
+    m_fullscreenElement->didStopBeingFullscreenElement();
 
     m_areKeysEnabledInFullscreen = false;
 

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (262455 => 262456)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2020-06-02 22:26:02 UTC (rev 262456)
@@ -5992,6 +5992,9 @@
     if (m_videoFullscreenMode == mode)
         return;
 
+    if (m_waitingToEnterFullscreen)
+        return;
+
 #if ENABLE(FULLSCREEN_API) && ENABLE(VIDEO_USES_ELEMENT_FULLSCREEN)
     if (document().settings().fullScreenEnabled() && mode == VideoFullscreenModeStandard) {
         m_temporarilyAllowingInlinePlaybackAfterFullscreen = false;

Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (262455 => 262456)


--- trunk/Source/WebCore/html/HTMLMediaElement.h	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h	2020-06-02 22:26:02 UTC (rev 262456)
@@ -561,7 +561,7 @@
 
     bool isSuspended() const final;
 
-    WEBCORE_EXPORT void didBecomeFullscreenElement() final;
+    WEBCORE_EXPORT void didBecomeFullscreenElement() override;
     WEBCORE_EXPORT void willExitFullscreen();
 
 #if ENABLE(PICTURE_IN_PICTURE_API)

Modified: trunk/Source/WebCore/html/HTMLVideoElement.cpp (262455 => 262456)


--- trunk/Source/WebCore/html/HTMLVideoElement.cpp	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebCore/html/HTMLVideoElement.cpp	2020-06-02 22:26:02 UTC (rev 262456)
@@ -348,7 +348,9 @@
 
 bool HTMLVideoElement::webkitDisplayingFullscreen()
 {
-    return isFullscreen() && !waitingToEnterFullscreen();
+    // This function starts to return true after the video element has entered
+    // fullscreen/picture-in-picture until it has exited fullscreen/picture-in-picture
+    return (isFullscreen() && !waitingToEnterFullscreen()) || (!isFullscreen() && m_isChangingPresentationMode);
 }
 
 void HTMLVideoElement::ancestorWillEnterFullscreen()
@@ -467,10 +469,15 @@
 {
     INFO_LOG(LOGIDENTIFIER, ", mode = ", mode);
 
+    if (m_isChangingPresentationMode)
+        return;
+
     if (mode == VideoFullscreenModeNone) {
         if (isFullscreen()) {
             if (toPresentationMode(fullscreenMode()) == VideoPresentationMode::PictureInPicture)
                 m_isEnteringOrExitingPictureInPicture = true;
+
+            m_isChangingPresentationMode = true;
             exitFullscreen();
         }
 
@@ -483,7 +490,10 @@
     if (mode == VideoFullscreenModePictureInPicture)
         m_isEnteringOrExitingPictureInPicture = true;
 
-    enterFullscreen(mode);
+    if (mode != fullscreenMode()) {
+        m_isChangingPresentationMode = true;
+        enterFullscreen(mode);
+    }
 }
 
 auto HTMLVideoElement::webkitPresentationMode() const -> VideoPresentationMode
@@ -504,14 +514,18 @@
     HTMLMediaElement::fullscreenModeChanged(mode);
 }
 
-void HTMLVideoElement::didEnterFullscreen()
+void HTMLVideoElement::didBecomeFullscreenElement()
 {
+    m_isChangingPresentationMode = false;
     if (m_isEnteringOrExitingPictureInPicture)
         m_isWaitingForPictureInPictureWindowFrame = true;
+
+    HTMLMediaElement::didBecomeFullscreenElement();
 }
 
-void HTMLVideoElement::didExitFullscreen()
+void HTMLVideoElement::didStopBeingFullscreenElement()
 {
+    m_isChangingPresentationMode = false;
     if (m_isEnteringOrExitingPictureInPicture) {
         m_isEnteringOrExitingPictureInPicture = false;
 #if ENABLE(PICTURE_IN_PICTURE_API)

Modified: trunk/Source/WebCore/html/HTMLVideoElement.h (262455 => 262456)


--- trunk/Source/WebCore/html/HTMLVideoElement.h	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebCore/html/HTMLVideoElement.h	2020-06-02 22:26:02 UTC (rev 262456)
@@ -89,8 +89,8 @@
     void setFullscreenMode(VideoFullscreenMode);
     void fullscreenModeChanged(VideoFullscreenMode) final;
 
-    WEBCORE_EXPORT void didEnterFullscreen();
-    WEBCORE_EXPORT void didExitFullscreen();
+    WEBCORE_EXPORT void didBecomeFullscreenElement() final;
+    WEBCORE_EXPORT void didStopBeingFullscreenElement() final;
     void setVideoFullscreenFrame(FloatRect) final;
 
 #if ENABLE(PICTURE_IN_PICTURE_API)
@@ -134,6 +134,7 @@
     unsigned m_lastReportedVideoWidth { 0 };
     unsigned m_lastReportedVideoHeight { 0 };
 
+    bool m_isChangingPresentationMode { false };
     bool m_isEnteringOrExitingPictureInPicture { false };
     bool m_isWaitingForPictureInPictureWindowFrame { false };
 #if ENABLE(PICTURE_IN_PICTURE_API)

Modified: trunk/Source/WebKit/ChangeLog (262455 => 262456)


--- trunk/Source/WebKit/ChangeLog	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebKit/ChangeLog	2020-06-02 22:26:02 UTC (rev 262456)
@@ -1,3 +1,14 @@
+2020-06-02  Peng Liu  <peng.l...@apple.com>
+
+        Stressing webkitSetPresentationMode leads to wrong inline video dimensions
+        https://bugs.webkit.org/show_bug.cgi?id=202425
+
+        Reviewed by Eric Carlson.
+
+        * WebProcess/cocoa/VideoFullscreenManager.mm:
+        (WebKit::VideoFullscreenManager::didEnterFullscreen):
+        (WebKit::VideoFullscreenManager::didCleanupFullscreen):
+
 2020-06-02  Kate Cheney  <katherine_che...@apple.com>
 
         Assert network process is not suspended when trying to merge new ITP data

Modified: trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm (262455 => 262456)


--- trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm	2020-06-02 22:26:02 UTC (rev 262456)
@@ -441,8 +441,6 @@
     if (!videoElement)
         return;
 
-    videoElement->didEnterFullscreen();
-
     dispatch_async(dispatch_get_main_queue(), [protectedThis = makeRefPtr(this), videoElement] {
         videoElement->didBecomeFullscreenElement();
     });
@@ -508,7 +506,7 @@
     model->setVideoFullscreenLayer(nil);
     RefPtr<HTMLVideoElement> videoElement = model->videoElement();
     if (videoElement)
-        videoElement->didExitFullscreen();
+        videoElement->didStopBeingFullscreenElement();
 
     interface->setFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone);
     interface->setFullscreenStandby(false);

Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (262455 => 262456)


--- trunk/Source/WebKitLegacy/mac/ChangeLog	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog	2020-06-02 22:26:02 UTC (rev 262456)
@@ -1,3 +1,27 @@
+2020-06-02  Peng Liu  <peng.l...@apple.com>
+
+        Stressing webkitSetPresentationMode leads to wrong inline video dimensions
+        https://bugs.webkit.org/show_bug.cgi?id=202425
+
+        Reviewed by Eric Carlson.
+
+        Move DumpRenderTree's implementation of the mock video presentation mode from WebView
+        to WebChromeClient and call videoElement.didStopBeingFullscreenElement() when a video
+        element exits fullscreen.
+
+        * WebCoreSupport/WebChromeClient.h:
+        * WebCoreSupport/WebChromeClient.mm:
+        (WebChromeClient::setMockVideoPresentationModeEnabled):
+        (WebChromeClient::enterVideoFullscreenForVideoElement):
+        (WebChromeClient::exitVideoFullscreenForVideoElement):
+        (WebChromeClient::exitVideoFullscreenToModeWithoutAnimation):
+        * WebView/WebView.mm:
+        (-[WebView _enterVideoFullscreenForVideoElement:mode:]):
+        (-[WebView _exitVideoFullscreen]):
+        (-[WebView _setMockVideoPresentationModeEnabled:]): Deleted.
+        * WebView/WebViewData.h:
+        * WebView/WebViewInternal.h:
+
 2020-06-01  David Kilzer  <ddkil...@apple.com>
 
         Don't use casts to convert between WebCore::DragDestinationAction and {Web,WK}DragDestinationAction types

Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h (262455 => 262456)


--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h	2020-06-02 22:26:02 UTC (rev 262456)
@@ -236,5 +236,6 @@
 
     String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const URL&) const final;
 
+    bool m_mockVideoPresentationModeEnabled { false };
     WebView *m_webView;
 };

Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm (262455 => 262456)


--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm	2020-06-02 22:26:02 UTC (rev 262456)
@@ -72,6 +72,7 @@
 #import <WebCore/HTMLInputElement.h>
 #import <WebCore/HTMLNames.h>
 #import <WebCore/HTMLPlugInImageElement.h>
+#import <WebCore/HTMLVideoElement.h>
 #import <WebCore/HitTestResult.h>
 #import <WebCore/Icon.h>
 #import <WebCore/IntPoint.h>
@@ -969,7 +970,7 @@
 
 void WebChromeClient::setMockVideoPresentationModeEnabled(bool enabled)
 {
-    [m_webView _setMockVideoPresentationModeEnabled:enabled];
+    m_mockVideoPresentationModeEnabled = enabled;
 }
 
 void WebChromeClient::enterVideoFullscreenForVideoElement(HTMLVideoElement& videoElement, HTMLMediaElementEnums::VideoFullscreenMode mode, bool standby)
@@ -977,14 +978,20 @@
     ASSERT_UNUSED(standby, !standby);
     ASSERT(mode != HTMLMediaElementEnums::VideoFullscreenModeNone);
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    [m_webView _enterVideoFullscreenForVideoElement:&videoElement mode:mode];
+    if (m_mockVideoPresentationModeEnabled)
+        videoElement.didBecomeFullscreenElement();
+    else
+        [m_webView _enterVideoFullscreenForVideoElement:&videoElement mode:mode];
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 
-void WebChromeClient::exitVideoFullscreenForVideoElement(WebCore::HTMLVideoElement&)
+void WebChromeClient::exitVideoFullscreenForVideoElement(WebCore::HTMLVideoElement& videoElement)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    [m_webView _exitVideoFullscreen];
+    if (m_mockVideoPresentationModeEnabled)
+        videoElement.didStopBeingFullscreenElement();
+    else
+        [m_webView _exitVideoFullscreen];
     END_BLOCK_OBJC_EXCEPTIONS;    
 }
 
@@ -991,7 +998,10 @@
 void WebChromeClient::exitVideoFullscreenToModeWithoutAnimation(HTMLVideoElement& videoElement, HTMLMediaElementEnums::VideoFullscreenMode targetMode)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    [m_webView _exitVideoFullscreen];
+    if (m_mockVideoPresentationModeEnabled)
+        videoElement.didStopBeingFullscreenElement();
+    else
+        [m_webView _exitVideoFullscreen];
     END_BLOCK_OBJC_EXCEPTIONS;
 }
 

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebView.mm (262455 => 262456)


--- trunk/Source/WebKitLegacy/mac/WebView/WebView.mm	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebView.mm	2020-06-02 22:26:02 UTC (rev 262456)
@@ -9289,18 +9289,8 @@
 
 #if ENABLE(VIDEO_PRESENTATION_MODE)
 
-- (void)_setMockVideoPresentationModeEnabled:(BOOL)enabled
-{
-    _private->mockVideoPresentationModeEnabled = enabled;
-}
-
 - (void)_enterVideoFullscreenForVideoElement:(NakedPtr<WebCore::HTMLVideoElement>)videoElement mode:(WebCore::HTMLMediaElementEnums::VideoFullscreenMode)mode
 {
-    if (_private->mockVideoPresentationModeEnabled) {
-        videoElement->didBecomeFullscreenElement();
-        return;
-    }
-
     if (_private->fullscreenController) {
         if ([_private->fullscreenController videoElement] == videoElement) {
             // The backend may just warn us that the underlaying plaftormMovie()
@@ -9329,9 +9319,6 @@
 
 - (void)_exitVideoFullscreen
 {
-    if (_private->mockVideoPresentationModeEnabled)
-        return;
-
     if (!_private->fullscreenController && _private->fullscreenControllersExiting.isEmpty())
         return;
 

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebViewData.h (262455 => 262456)


--- trunk/Source/WebKitLegacy/mac/WebView/WebViewData.h	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebViewData.h	2020-06-02 22:26:02 UTC (rev 262456)
@@ -323,10 +323,6 @@
     Vector<RetainPtr<WebVideoFullscreenController>> fullscreenControllersExiting;
 #endif
 
-#if ENABLE(VIDEO_PRESENTATION_MODE)
-    BOOL mockVideoPresentationModeEnabled;
-#endif
-
 #if PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
     RefPtr<WebCore::PlaybackSessionModelMediaElement> playbackSessionModel;
     RefPtr<WebCore::PlaybackSessionInterfaceMac> playbackSessionInterface;

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebViewInternal.h (262455 => 262456)


--- trunk/Source/WebKitLegacy/mac/WebView/WebViewInternal.h	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebViewInternal.h	2020-06-02 22:26:02 UTC (rev 262456)
@@ -270,7 +270,6 @@
 
 #if ENABLE(VIDEO) && defined(__cplusplus)
 #if ENABLE(VIDEO_PRESENTATION_MODE)
-- (void)_setMockVideoPresentationModeEnabled:(BOOL)enabled;
 - (void)_enterVideoFullscreenForVideoElement:(NakedPtr<WebCore::HTMLVideoElement>)videoElement mode:(WebCore::HTMLMediaElementEnums::VideoFullscreenMode)mode;
 - (void)_exitVideoFullscreen;
 #if PLATFORM(MAC)

Modified: trunk/Tools/ChangeLog (262455 => 262456)


--- trunk/Tools/ChangeLog	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Tools/ChangeLog	2020-06-02 22:26:02 UTC (rev 262456)
@@ -1,3 +1,13 @@
+2020-06-02  Peng Liu  <peng.l...@apple.com>
+
+        Stressing webkitSetPresentationMode leads to wrong inline video dimensions
+        https://bugs.webkit.org/show_bug.cgi?id=202425
+
+        Reviewed by Eric Carlson.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewCloseAllMediaPresentations.mm:
+        (TEST):
+
 2020-06-02  Youenn Fablet  <you...@apple.com>
 
         Allow using web processes for service workers even though they loaded about URLs

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewCloseAllMediaPresentations.mm (262455 => 262456)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewCloseAllMediaPresentations.mm	2020-06-02 22:13:07 UTC (rev 262455)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewCloseAllMediaPresentations.mm	2020-06-02 22:26:02 UTC (rev 262456)
@@ -38,16 +38,20 @@
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get() addToWindow:YES]);
 
     [webView synchronouslyLoadHTMLString:@"<video src="" webkit-playsinline></video>"];
-    [webView objectByEvaluatingJavaScript:@"document.querySelector('video').addEventListener('webkitpresentationmodechanged', event => { window.webkit.messageHandlers.testHandler.postMessage('presentationmodechanged'); });"];
 
-    __block bool presentationModeChanged = false;
-    [webView performAfterReceivingMessage:@"presentationmodechanged" action:^{ presentationModeChanged = true; }];
-
     [webView objectByEvaluatingJavaScriptWithUserGesture:@"document.querySelector('video').webkitSetPresentationMode('picture-in-picture')"];
 
-    TestWebKitAPI::Util::run(&presentationModeChanged);
+    do {
+        id result = [webView objectByEvaluatingJavaScript:@"document.querySelector('video').webkitDisplayingFullscreen"];
+        if ([result boolValue])
+            break;
 
-    presentationModeChanged = false;
+        TestWebKitAPI::Util::sleep(0.5);
+    } while (true);
+
+    [webView objectByEvaluatingJavaScript:@"document.querySelector('video').addEventListener('webkitpresentationmodechanged', event => { window.webkit.messageHandlers.testHandler.postMessage('presentationmodechanged'); });"];
+
+    __block bool presentationModeChanged = false;
     [webView performAfterReceivingMessage:@"presentationmodechanged" action:^{ presentationModeChanged = true; }];
 
     [webView _closeAllMediaPresentations];
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to