Title: [267053] trunk/Source
Revision
267053
Author
[email protected]
Date
2020-09-14 15:39:50 -0700 (Mon, 14 Sep 2020)

Log Message

Returning to element fullscreen from PiP is not stable under stress tests
https://bugs.webkit.org/show_bug.cgi?id=216287

Reviewed by Jer Noble.

Source/WebCore:

* platform/cocoa/VideoFullscreenChangeObserver.h:
Delete prepareToExitFullscreen().

* platform/ios/VideoFullscreenInterfaceAVKit.h:
* platform/ios/VideoFullscreenInterfaceAVKit.mm:
(VideoFullscreenInterfaceAVKit::VideoFullscreenInterfaceAVKit):
(VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStop):
(VideoFullscreenInterfaceAVKit::didStopPictureInPicture):
(VideoFullscreenInterfaceAVKit::stopPictureInPictureTimerFired):
(VideoFullscreenInterfaceAVKit::setReadyToStopPictureInPicture):
VideoFullscreenInterfaceAVKit expects an element enters fullscreen and figure out the
location and size of the video element after that, which will be used by AVKit for the
exiting picture-in-picture animation. However, the entering fullscreen may take a long
time and AVKit will start exiting picture-in-picture before the entering fullscreen
transition is done. We need to add protection for such a scenario. This patch adds
a timer (m_stopPictureInPictureTimer) for this purpose. This patch also makes sure
VideoFullscreenInterfaceAVKit will call didExitPictureInPicture() properly.

* platform/ios/WebVideoFullscreenControllerAVKit.mm:
Delete prepareToExitFullscreen().

* platform/mac/VideoFullscreenInterfaceMac.mm:
(WebCore::VideoFullscreenInterfaceMac::preparedToReturnToInline): This function
is not used on Mac.

Source/WebKit:

* UIProcess/Cocoa/VideoFullscreenManagerProxy.h:
(WebKit::VideoFullscreenManagerProxyClient::~VideoFullscreenManagerProxyClient):
(WebKit::VideoFullscreenManagerProxy::setClient):
(WebKit::VideoFullscreenManagerProxy::client const):
* UIProcess/Cocoa/VideoFullscreenManagerProxy.mm:
(WebKit::VideoFullscreenModelContext::didEnterPictureInPicture):
(WebKit::VideoFullscreenModelContext::didExitPictureInPicture):
(WebKit::VideoFullscreenModelContext::willEnterPictureInPicture):
(WebKit::VideoFullscreenManagerProxy::hasVideoInPictureInPictureDidChange):
(WebKit::VideoFullscreenManagerProxy::fullscreenMayReturnToInline):
(WebKit::VideoFullscreenModelContext::prepareToExitFullscreen): Deleted.
Add the interface VideoFullscreenManagerProxyClient, which is used by WKFullScreenWindowController
to implement the support of "returning to element fullscreen from PiP". Using VideoFullscreenModelClient
for that purpose is not a good idea because the instance observed by VideoFullscreenModelClient may be
destroyed when a video element is exiting picture-in-picture if we don't call
VideoFullscreenManagerProxy::addClientForContext() and VideoFullscreenManagerProxy::removeClientForContext()
properly.

* UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
(-[WKFullScreenWindowController initWithWebView:]):
(-[WKFullScreenWindowController dealloc]):
(-[WKFullScreenWindowController beganEnterFullScreenWithInitialFrame:finalFrame:]):
(-[WKFullScreenWindowController _completedExitFullScreen]):
(-[WKFullScreenWindowController videoControlsManagerDidChange]):
(-[WKFullScreenWindowController prepareToExitPictureInPicture]):
(-[WKFullScreenWindowController didExitPictureInPicture]):
(-[WKFullScreenWindowController _videoFullscreenManager]):
(WKFullScreenWindowControllerVideoFullscreenModelClient::setParent): Deleted.
(WKFullScreenWindowControllerVideoFullscreenModelClient::setInterface): Deleted.
(WKFullScreenWindowControllerVideoFullscreenModelClient::interface const): Deleted.
(-[WKFullScreenWindowController willEnterPictureInPicture]): Deleted.
(-[WKFullScreenWindowController failedToEnterPictureInPicture]): Deleted.
Use VideoFullscreenManagerProxyClient instead of VideoFullscreenModelClient to implement
the support of "returning to element fullscreen from PiP" on iOS.
A user can "return to element fullscreen from PiP" by clicking the "return to fullscreen"
button on the PiP window, or by clicking the "fullscreen" button on the page. This patch
adds support for the latter case.

* UIProcess/mac/WKFullScreenWindowController.h:
* UIProcess/mac/WKFullScreenWindowController.mm:
(-[WKFullScreenWindowController initWithWindow:webView:page:]):
(-[WKFullScreenWindowController dealloc]):
(-[WKFullScreenWindowController videoControlsManagerDidChange]):
(-[WKFullScreenWindowController didExitPictureInPicture]):
(-[WKFullScreenWindowController windowDidEnterFullScreen:]):
(-[WKFullScreenWindowController _videoFullscreenManager]):
(WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient::setParent): Deleted.
(WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient::setInterface): Deleted.
(WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient::interface const): Deleted.
Use VideoFullscreenManagerProxyClient instead of VideoFullscreenModelClient to implement the
support of "exiting fullscreen after entering PiP" on Mac. We may implement the support of
"returning to element fullscreen from PiP" on Mac in the future.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (267052 => 267053)


--- trunk/Source/WebCore/ChangeLog	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebCore/ChangeLog	2020-09-14 22:39:50 UTC (rev 267053)
@@ -1,3 +1,35 @@
+2020-09-14  Peng Liu  <[email protected]>
+
+        Returning to element fullscreen from PiP is not stable under stress tests
+        https://bugs.webkit.org/show_bug.cgi?id=216287
+
+        Reviewed by Jer Noble.
+
+        * platform/cocoa/VideoFullscreenChangeObserver.h:
+        Delete prepareToExitFullscreen().
+
+        * platform/ios/VideoFullscreenInterfaceAVKit.h:
+        * platform/ios/VideoFullscreenInterfaceAVKit.mm:
+        (VideoFullscreenInterfaceAVKit::VideoFullscreenInterfaceAVKit):
+        (VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStop):
+        (VideoFullscreenInterfaceAVKit::didStopPictureInPicture):
+        (VideoFullscreenInterfaceAVKit::stopPictureInPictureTimerFired):
+        (VideoFullscreenInterfaceAVKit::setReadyToStopPictureInPicture):
+        VideoFullscreenInterfaceAVKit expects an element enters fullscreen and figure out the
+        location and size of the video element after that, which will be used by AVKit for the
+        exiting picture-in-picture animation. However, the entering fullscreen may take a long
+        time and AVKit will start exiting picture-in-picture before the entering fullscreen
+        transition is done. We need to add protection for such a scenario. This patch adds
+        a timer (m_stopPictureInPictureTimer) for this purpose. This patch also makes sure
+        VideoFullscreenInterfaceAVKit will call didExitPictureInPicture() properly.
+
+        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
+        Delete prepareToExitFullscreen().
+
+        * platform/mac/VideoFullscreenInterfaceMac.mm:
+        (WebCore::VideoFullscreenInterfaceMac::preparedToReturnToInline): This function
+        is not used on Mac.
+
 2020-09-14  Sam Weinig  <[email protected]>
 
         [WebIDL] Move synthetic operation creation from IDLParser to CodeGeneratorJS

Modified: trunk/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h (267052 => 267053)


--- trunk/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h	2020-09-14 22:39:50 UTC (rev 267053)
@@ -41,7 +41,6 @@
     virtual void willExitFullscreen() = 0;
     virtual void didExitFullscreen() = 0;
     virtual void didCleanupFullscreen() = 0;
-    virtual void prepareToExitFullscreen() = 0;
     virtual void fullscreenMayReturnToInline() = 0;
     virtual void fullscreenWillReturnToInline() = 0;
 };

Modified: trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h (267052 => 267053)


--- trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h	2020-09-14 22:39:50 UTC (rev 267053)
@@ -166,6 +166,7 @@
     void returnToStandby();
     void doEnterFullscreen();
     void watchdogTimerFired();
+    void stopPictureInPictureTimerFired();
     WebAVPlayerController *playerController() const;
 
     Ref<PlaybackSessionInterfaceAVKit> m_playbackSessionInterface;
@@ -183,6 +184,7 @@
     RetainPtr<WebAVPlayerLayerView> m_playerLayerView;
     WTF::Function<void(bool)> m_prepareToInlineCallback;
     RunLoop::Timer<VideoFullscreenInterfaceAVKit> m_watchdogTimer;
+    RunLoop::Timer<VideoFullscreenInterfaceAVKit> m_stopPictureInPictureTimer;
     FloatRect m_inlineRect;
     RouteSharingPolicy m_routeSharingPolicy { RouteSharingPolicy::Default };
     String m_routingContextUID;

Modified: trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm (267052 => 267053)


--- trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm	2020-09-14 22:39:50 UTC (rev 267053)
@@ -85,6 +85,7 @@
 #endif
 
 static const Seconds defaultWatchdogTimerInterval { 1_s };
+static const Seconds stopPictureInPictureTimerInterval { 1_s };
 static bool ignoreWatchdogForDebugging = false;
 
 @interface AVPlayerViewController (Details)
@@ -812,6 +813,7 @@
     : m_playbackSessionInterface(playbackSessionInterface)
     , m_playerViewControllerDelegate(adoptNS([[WebAVPlayerViewControllerDelegate alloc] init]))
     , m_watchdogTimer(RunLoop::main(), this, &VideoFullscreenInterfaceAVKit::watchdogTimerFired)
+    , m_stopPictureInPictureTimer(RunLoop::main(), this, &VideoFullscreenInterfaceAVKit::stopPictureInPictureTimerFired)
 {
 }
 
@@ -1084,7 +1086,6 @@
     m_prepareToInlineCallback = WTFMove(callback);
     if (m_fullscreenChangeObserver) {
         m_fullscreenChangeObserver->fullscreenMayReturnToInline();
-        m_fullscreenChangeObserver->prepareToExitFullscreen();
         if (m_readyToStopPictureInPicture)
             m_fullscreenChangeObserver->fullscreenWillReturnToInline();
     }
@@ -1176,6 +1177,11 @@
 
         if (m_exitFullscreenNeedsExitPictureInPicture)
             doExitFullscreen();
+        else if (m_exitingPictureInPicture) {
+            m_exitingPictureInPicture = false;
+            if (m_videoFullscreenModel)
+                m_videoFullscreenModel->didExitPictureInPicture();
+        }
 
         if (m_enterFullscreenNeedsExitPictureInPicture)
             doEnterFullscreen();
@@ -1182,19 +1188,26 @@
         return;
     }
 
+    if (!m_readyToStopPictureInPicture) {
+        if (!m_stopPictureInPictureTimer.isActive())
+            m_stopPictureInPictureTimer.startOneShot(stopPictureInPictureTimerInterval);
+    } else
+        clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture);
+
     [m_playerLayerView setBackgroundColor:clearUIColor()];
     [[m_playerViewController view] setBackgroundColor:clearUIColor()];
 
-    if (m_videoFullscreenModel)
-        m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone);
-
-    clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture);
-
     if (m_enterFullscreenNeedsExitPictureInPicture)
         doEnterFullscreen();
 
     if (m_exitFullscreenNeedsExitPictureInPicture)
         doExitFullscreen();
+    else if (m_exitingPictureInPicture) {
+        m_exitingPictureInPicture = false;
+
+        if (m_videoFullscreenModel)
+            m_videoFullscreenModel->didExitPictureInPicture();
+    }
 }
 
 void VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStopWithCompletionHandler(void (^completionHandler)(BOOL restored))
@@ -1572,6 +1585,13 @@
     [[m_playerViewController view] setHidden:YES];
 }
 
+void VideoFullscreenInterfaceAVKit::stopPictureInPictureTimerFired()
+{
+    LOG(Fullscreen, "VideoFullscreenInterfaceAVKit::stopPictureInPictureTimerFired(%p) - not ready to stop picture-in-picture in %gs; forcing stop picture-in-picture.", this, stopPictureInPictureTimerInterval.value());
+    m_stopPictureInPictureTimer.stop();
+    clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture);
+}
+
 void VideoFullscreenInterfaceAVKit::setMode(HTMLMediaElementEnums::VideoFullscreenMode mode)
 {
     if ((m_currentMode.mode() & mode) == mode)
@@ -1605,8 +1625,15 @@
         return;
 
     m_readyToStopPictureInPicture = ready;
-    if (m_readyToStopPictureInPicture && m_fullscreenChangeObserver)
-        m_fullscreenChangeObserver->fullscreenWillReturnToInline();
+    if (m_readyToStopPictureInPicture) {
+        if (m_stopPictureInPictureTimer.isActive()) {
+            m_stopPictureInPictureTimer.stop();
+            clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture);
+        }
+
+        if (m_fullscreenChangeObserver)
+            m_fullscreenChangeObserver->fullscreenWillReturnToInline();
+    }
 }
 
 static Optional<bool> isPictureInPictureSupported;

Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm (267052 => 267053)


--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm	2020-09-14 22:39:50 UTC (rev 267053)
@@ -128,7 +128,6 @@
     void willExitFullscreen() final;
     void didExitFullscreen() final;
     void didCleanupFullscreen() final;
-    void prepareToExitFullscreen() final { }
     void fullscreenMayReturnToInline() final { }
     void fullscreenWillReturnToInline() final;
 

Modified: trunk/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm (267052 => 267053)


--- trunk/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm	2020-09-14 22:39:50 UTC (rev 267053)
@@ -552,15 +552,9 @@
 
 void VideoFullscreenInterfaceMac::preparedToReturnToInline(bool visible, const IntRect& inlineRect, NSWindow *parentWindow)
 {
-    LOG(Fullscreen, "VideoFullscreenInterfaceMac::preparedToReturnToInline(%p), visible:%s, inlineRect:{%d, %d, %d, %d}, parentWindow:%p", this, boolString(visible), inlineRect.x(), inlineRect.y(), inlineRect.width(), inlineRect.height(), parentWindow);
-
-    if (!visible) {
-        [m_webVideoFullscreenInterfaceObjC exitPIP];
-        return;
-    }
-
-    ASSERT(parentWindow);
-    [m_webVideoFullscreenInterfaceObjC exitPIPAnimatingToRect:(NSRect)inlineRect inWindow:parentWindow];
+    UNUSED_PARAM(visible);
+    UNUSED_PARAM(inlineRect);
+    UNUSED_PARAM(parentWindow);
 }
 
 void VideoFullscreenInterfaceMac::externalPlaybackChanged(bool enabled, PlaybackSessionModel::ExternalPlaybackTargetType, const String&)

Modified: trunk/Source/WebKit/ChangeLog (267052 => 267053)


--- trunk/Source/WebKit/ChangeLog	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebKit/ChangeLog	2020-09-14 22:39:50 UTC (rev 267053)
@@ -1,3 +1,63 @@
+2020-09-14  Peng Liu  <[email protected]>
+
+        Returning to element fullscreen from PiP is not stable under stress tests
+        https://bugs.webkit.org/show_bug.cgi?id=216287
+
+        Reviewed by Jer Noble.
+
+        * UIProcess/Cocoa/VideoFullscreenManagerProxy.h:
+        (WebKit::VideoFullscreenManagerProxyClient::~VideoFullscreenManagerProxyClient):
+        (WebKit::VideoFullscreenManagerProxy::setClient):
+        (WebKit::VideoFullscreenManagerProxy::client const):
+        * UIProcess/Cocoa/VideoFullscreenManagerProxy.mm:
+        (WebKit::VideoFullscreenModelContext::didEnterPictureInPicture):
+        (WebKit::VideoFullscreenModelContext::didExitPictureInPicture):
+        (WebKit::VideoFullscreenModelContext::willEnterPictureInPicture):
+        (WebKit::VideoFullscreenManagerProxy::hasVideoInPictureInPictureDidChange):
+        (WebKit::VideoFullscreenManagerProxy::fullscreenMayReturnToInline):
+        (WebKit::VideoFullscreenModelContext::prepareToExitFullscreen): Deleted.
+        Add the interface VideoFullscreenManagerProxyClient, which is used by WKFullScreenWindowController
+        to implement the support of "returning to element fullscreen from PiP". Using VideoFullscreenModelClient
+        for that purpose is not a good idea because the instance observed by VideoFullscreenModelClient may be
+        destroyed when a video element is exiting picture-in-picture if we don't call
+        VideoFullscreenManagerProxy::addClientForContext() and VideoFullscreenManagerProxy::removeClientForContext()
+        properly.
+
+        * UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
+        (-[WKFullScreenWindowController initWithWebView:]):
+        (-[WKFullScreenWindowController dealloc]):
+        (-[WKFullScreenWindowController beganEnterFullScreenWithInitialFrame:finalFrame:]):
+        (-[WKFullScreenWindowController _completedExitFullScreen]):
+        (-[WKFullScreenWindowController videoControlsManagerDidChange]):
+        (-[WKFullScreenWindowController prepareToExitPictureInPicture]):
+        (-[WKFullScreenWindowController didExitPictureInPicture]):
+        (-[WKFullScreenWindowController _videoFullscreenManager]):
+        (WKFullScreenWindowControllerVideoFullscreenModelClient::setParent): Deleted.
+        (WKFullScreenWindowControllerVideoFullscreenModelClient::setInterface): Deleted.
+        (WKFullScreenWindowControllerVideoFullscreenModelClient::interface const): Deleted.
+        (-[WKFullScreenWindowController willEnterPictureInPicture]): Deleted.
+        (-[WKFullScreenWindowController failedToEnterPictureInPicture]): Deleted.
+        Use VideoFullscreenManagerProxyClient instead of VideoFullscreenModelClient to implement
+        the support of "returning to element fullscreen from PiP" on iOS.
+        A user can "return to element fullscreen from PiP" by clicking the "return to fullscreen"
+        button on the PiP window, or by clicking the "fullscreen" button on the page. This patch
+        adds support for the latter case.
+
+        * UIProcess/mac/WKFullScreenWindowController.h:
+        * UIProcess/mac/WKFullScreenWindowController.mm:
+        (-[WKFullScreenWindowController initWithWindow:webView:page:]):
+        (-[WKFullScreenWindowController dealloc]):
+        (-[WKFullScreenWindowController videoControlsManagerDidChange]):
+        (-[WKFullScreenWindowController didExitPictureInPicture]):
+        (-[WKFullScreenWindowController windowDidEnterFullScreen:]):
+        (-[WKFullScreenWindowController _videoFullscreenManager]):
+        (WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient::setParent): Deleted.
+        (WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient::setInterface): Deleted.
+        (WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient::interface const): Deleted.
+        Use VideoFullscreenManagerProxyClient instead of VideoFullscreenModelClient to implement the
+        support of "exiting fullscreen after entering PiP" on Mac. We may implement the support of
+        "returning to element fullscreen from PiP" on Mac in the future.
+
 2020-09-14  Alex Christensen  <[email protected]>
 
         Move cookie flushing SPI from WKProcessPool to WKHTTPCookieStore

Modified: trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h (267052 => 267053)


--- trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h	2020-09-14 22:39:50 UTC (rev 267053)
@@ -111,7 +111,6 @@
     void willExitFullscreen() final;
     void didExitFullscreen() final;
     void didCleanupFullscreen() final;
-    void prepareToExitFullscreen() final;
     void fullscreenMayReturnToInline() final;
     void fullscreenWillReturnToInline() final;
 
@@ -124,6 +123,14 @@
     bool m_hasVideo { false };
 };
 
+class VideoFullscreenManagerProxyClient : public CanMakeWeakPtr<VideoFullscreenManagerProxyClient> {
+public:
+    virtual ~VideoFullscreenManagerProxyClient() { };
+
+    virtual void fullscreenMayReturnToInline() = 0;
+    virtual void hasVideoInPictureInPictureDidChange(bool value) = 0;
+};
+
 class VideoFullscreenManagerProxy : public RefCounted<VideoFullscreenManagerProxy>, private IPC::MessageReceiver {
 public:
     static Ref<VideoFullscreenManagerProxy> create(WebPageProxy&, PlaybackSessionManagerProxy&);
@@ -144,6 +151,8 @@
     bool isPlayingVideoInEnhancedFullscreen() const;
 
     PlatformVideoFullscreenInterface* controlsManagerInterface();
+    void setClient(VideoFullscreenManagerProxyClient* client) { m_client = makeWeakPtr(client); }
+    VideoFullscreenManagerProxyClient* client() const { return m_client.get(); }
 
     void forEachSession(Function<void(WebCore::VideoFullscreenModel&, PlatformVideoFullscreenInterface&)>&&);
 
@@ -202,6 +211,7 @@
     HashMap<PlaybackSessionContextIdentifier, ModelInterfaceTuple> m_contextMap;
     PlaybackSessionContextIdentifier m_controlsManagerContextId;
     HashMap<PlaybackSessionContextIdentifier, int> m_clientCounts;
+    WeakPtr<VideoFullscreenManagerProxyClient> m_client;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm (267052 => 267053)


--- trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm	2020-09-14 22:39:50 UTC (rev 267053)
@@ -288,25 +288,22 @@
         completionHandler(WebCore::RouteSharingPolicy::Default, emptyString());
 }
 
-void VideoFullscreenModelContext::prepareToExitFullscreen()
+void VideoFullscreenModelContext::didEnterPictureInPicture()
 {
-    for (auto& client : copyToVector(m_clients))
-        client->prepareToExitPictureInPicture();
+    if (m_manager)
+        m_manager->hasVideoInPictureInPictureDidChange(true);
 }
 
-void VideoFullscreenModelContext::willEnterPictureInPicture()
+void VideoFullscreenModelContext::didExitPictureInPicture()
 {
-    for (auto& client : copyToVector(m_clients))
-        client->willEnterPictureInPicture();
+    if (m_manager)
+        m_manager->hasVideoInPictureInPictureDidChange(false);
 }
 
-void VideoFullscreenModelContext::didEnterPictureInPicture()
+void VideoFullscreenModelContext::willEnterPictureInPicture()
 {
-    if (m_manager)
-        m_manager->hasVideoInPictureInPictureDidChange(true);
-
     for (auto& client : copyToVector(m_clients))
-        client->didEnterPictureInPicture();
+        client->willEnterPictureInPicture();
 }
 
 void VideoFullscreenModelContext::failedToEnterPictureInPicture()
@@ -321,15 +318,6 @@
         client->willExitPictureInPicture();
 }
 
-void VideoFullscreenModelContext::didExitPictureInPicture()
-{
-    if (m_manager)
-        m_manager->hasVideoInPictureInPictureDidChange(false);
-
-    for (auto& client : copyToVector(m_clients))
-        client->didExitPictureInPicture();
-}
-
 #pragma mark - VideoFullscreenManagerProxy
 
 Ref<VideoFullscreenManagerProxy> VideoFullscreenManagerProxy::create(WebPageProxy& page, PlaybackSessionManagerProxy& playbackSessionManagerProxy)
@@ -520,6 +508,8 @@
 void VideoFullscreenManagerProxy::hasVideoInPictureInPictureDidChange(bool value)
 {
     m_page->uiClient().hasVideoInPictureInPictureDidChange(m_page, value);
+    if (m_client)
+        m_client->hasVideoInPictureInPictureDidChange(value);
 }
 
 #pragma mark Messages from VideoFullscreenManager
@@ -825,6 +815,8 @@
 void VideoFullscreenManagerProxy::fullscreenMayReturnToInline(PlaybackSessionContextIdentifier contextId)
 {
     m_page->fullscreenMayReturnToInline();
+    if (m_client)
+        m_client->fullscreenMayReturnToInline();
 }
 
 void VideoFullscreenManagerProxy::fullscreenWillReturnToInline(PlaybackSessionContextIdentifier contextId)

Modified: trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm (267052 => 267053)


--- trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm	2020-09-14 22:39:50 UTC (rev 267053)
@@ -24,9 +24,9 @@
  */
 
 #import "config.h"
+#import "WKFullScreenWindowControllerIOS.h"
 
 #if PLATFORM(IOS_FAMILY) && ENABLE(FULLSCREEN_API)
-#import "WKFullScreenWindowControllerIOS.h"
 
 #import "UIKitSPI.h"
 #import "VideoFullscreenManagerProxy.h"
@@ -427,61 +427,32 @@
 
 #pragma mark -
 
-@interface WKFullScreenWindowController (VideoFullscreenClientCallbacks)
-- (void)willEnterPictureInPicture;
+@interface WKFullScreenWindowController (VideoFullscreenManagerProxyClient)
 - (void)didEnterPictureInPicture;
-- (void)failedToEnterPictureInPicture;
 - (void)prepareToExitPictureInPicture;
 - (void)didExitPictureInPicture;
 @end
 
-class WKFullScreenWindowControllerVideoFullscreenModelClient : WebCore::VideoFullscreenModelClient {
+class WKFullScreenWindowControllerVideoFullscreenManagerProxyClient : public WebKit::VideoFullscreenManagerProxyClient {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     void setParent(WKFullScreenWindowController *parent) { m_parent = parent; }
 
-    void setInterface(WebCore::VideoFullscreenInterfaceAVKit* interface)
+private:
+    void fullscreenMayReturnToInline() final
     {
-        if (m_interface == interface)
-            return;
-
-        if (m_interface && m_interface->videoFullscreenModel())
-            m_interface->videoFullscreenModel()->removeClient(*this);
-        m_interface = interface;
-        if (m_interface && m_interface->videoFullscreenModel())
-            m_interface->videoFullscreenModel()->addClient(*this);
-    }
-
-    WebCore::VideoFullscreenInterfaceAVKit* interface() const { return m_interface.get(); }
-
-    void willEnterPictureInPicture() final
-    {
-        [m_parent willEnterPictureInPicture];
-    }
-
-    void didEnterPictureInPicture() final
-    {
-        [m_parent didEnterPictureInPicture];
-    }
-
-    void failedToEnterPictureInPicture() final
-    {
-        [m_parent failedToEnterPictureInPicture];
-    }
-
-    void prepareToExitPictureInPicture() final
-    {
         [m_parent prepareToExitPictureInPicture];
     }
 
-    void didExitPictureInPicture() final
+    void hasVideoInPictureInPictureDidChange(bool value) final
     {
-        [m_parent didExitPictureInPicture];
+        if (value)
+            [m_parent didEnterPictureInPicture];
+        else
+            [m_parent didExitPictureInPicture];
     }
 
-private:
     WKFullScreenWindowController *m_parent { nullptr };
-    RefPtr<WebCore::VideoFullscreenInterfaceAVKit> m_interface;
 };
 
 #pragma mark -
@@ -503,8 +474,9 @@
     RetainPtr<UIPinchGestureRecognizer> _interactivePinchDismissGestureRecognizer;
     RetainPtr<WKFullScreenInteractiveTransition> _interactiveDismissTransitionCoordinator;
 
-    WKFullScreenWindowControllerVideoFullscreenModelClient _videoFullscreenClient;
+    WKFullScreenWindowControllerVideoFullscreenManagerProxyClient _videoFullscreenManagerProxyClient;
     BOOL _inPictureInPicture;
+    BOOL _enterFullscreenNeedsExitPictureInPicture;
     BOOL _returnToFullscreenFromPictureInPicture;
 
     CGRect _initialFrame;
@@ -528,7 +500,7 @@
         return nil;
 
     self._webView = webView;
-    _videoFullscreenClient.setParent(self);
+    _videoFullscreenManagerProxyClient.setParent(self);
 
     return self;
 }
@@ -538,8 +510,7 @@
     [NSObject cancelPreviousPerformRequestsWithTarget:self];
     [[NSNotificationCenter defaultCenter] removeObserver:self];
 
-    _videoFullscreenClient.setInterface(nullptr);
-    _videoFullscreenClient.setParent(nullptr);
+    _videoFullscreenManagerProxyClient.setParent(nullptr);
 
     [super dealloc];
 }
@@ -725,16 +696,24 @@
             manager->setAnimatingFullScreen(false);
             page->setSuppressVisibilityUpdates(false);
 
-            auto* videoFullscreenManager = page->videoFullscreenManager();
-            auto* videoFullscreenInterface = videoFullscreenManager ? videoFullscreenManager->controlsManagerInterface() : nullptr;
-            if (_returnToFullscreenFromPictureInPicture) {
-                ASSERT(videoFullscreenInterface);
-                _returnToFullscreenFromPictureInPicture = NO;
-                if (videoFullscreenInterface)
-                    videoFullscreenInterface->setReadyToStopPictureInPicture(YES);
-            } else
-                _videoFullscreenClient.setInterface(videoFullscreenInterface);
+            if (auto* videoFullscreenManager = self._videoFullscreenManager) {
+                ASSERT(videoFullscreenManager->client() == nullptr);
+                videoFullscreenManager->setClient(&_videoFullscreenManagerProxyClient);
+                auto* videoFullscreenInterface = videoFullscreenManager ? videoFullscreenManager->controlsManagerInterface() : nullptr;
+                if (videoFullscreenInterface) {
+                    if (_returnToFullscreenFromPictureInPicture)
+                        videoFullscreenInterface->setReadyToStopPictureInPicture(YES);
+                    else if (_inPictureInPicture) {
+                        if (auto* model = videoFullscreenInterface->videoFullscreenModel()) {
+                            _enterFullscreenNeedsExitPictureInPicture = YES;
+                            model->requestFullscreenMode(WebCore::HTMLMediaElementEnums::VideoFullscreenModeNone);
+                        }
+                    }
+                }
+            }
 
+            _returnToFullscreenFromPictureInPicture = NO;
+
             return;
         }
 
@@ -850,6 +829,13 @@
         manager->didExitFullScreen();
     }
 
+    if (!_inPictureInPicture) {
+        if (auto* videoFullscreenManager = self._videoFullscreenManager) {
+            ASSERT(videoFullscreenManager->client() == &_videoFullscreenManagerProxyClient);
+            videoFullscreenManager->setClient(nullptr);
+        }
+    }
+
     [_window setHidden:YES];
     _window = nil;
 
@@ -868,9 +854,6 @@
             page->setNeedsDOMWindowResizeEvent();
         }
 
-        if (!_inPictureInPicture)
-            _videoFullscreenClient.setInterface(nullptr);
-
         _exitRequested = NO;
         _exitingFullScreen = NO;
         if (_enterRequested) {
@@ -904,11 +887,6 @@
 {
     if (_fullscreenViewController)
         [_fullscreenViewController videoControlsManagerDidChange];
-
-    auto page = [self._webView _page];
-    auto* videoFullscreenManager = page ? page->videoFullscreenManager() : nullptr;
-    auto* videoFullscreenInterface = videoFullscreenManager ? videoFullscreenManager->controlsManagerInterface() : nullptr;
-    _videoFullscreenClient.setInterface(videoFullscreenInterface);
 }
 
 - (void)placeholderWillMoveToSuperview:(UIView *)superview
@@ -922,15 +900,6 @@
     });
 }
 
-- (void)willEnterPictureInPicture
-{
-    auto* interface = _videoFullscreenClient.interface();
-    if (!interface || !interface->pictureInPictureWasStartedWhenEnteringBackground())
-        return;
-
-    [_fullscreenViewController setAnimatingViewAlpha:0];
-}
-
 - (void)didEnterPictureInPicture
 {
     _inPictureInPicture = YES;
@@ -937,22 +906,17 @@
     [self requestExitFullScreen];
 }
 
-- (void)failedToEnterPictureInPicture
+- (void)prepareToExitPictureInPicture
 {
-    auto* interface = _videoFullscreenClient.interface();
-    if (!interface || !interface->pictureInPictureWasStartedWhenEnteringBackground())
+    if (_enterFullscreenNeedsExitPictureInPicture)
         return;
 
-    [_fullscreenViewController setAnimatingViewAlpha:1];
-}
+    auto* videoFullscreenInterface = self._videoFullscreenManager ? self._videoFullscreenManager->controlsManagerInterface() : nullptr;
 
-- (void)prepareToExitPictureInPicture
-{
-    auto* interface = _videoFullscreenClient.interface();
-    if (!interface)
+    if (!videoFullscreenInterface)
         return;
 
-    interface->setReadyToStopPictureInPicture(NO);
+    videoFullscreenInterface->setReadyToStopPictureInPicture(NO);
     _returnToFullscreenFromPictureInPicture = YES;
 
     if (!_exitingFullScreen)
@@ -964,8 +928,13 @@
 - (void)didExitPictureInPicture
 {
     _inPictureInPicture = NO;
-    if (!_returnToFullscreenFromPictureInPicture && ![self isFullScreen])
-        _videoFullscreenClient.setInterface(nullptr);
+    _enterFullscreenNeedsExitPictureInPicture = NO;
+    if (![self isFullScreen]) {
+        if (auto* videoFullscreenManager = self._videoFullscreenManager) {
+            ASSERT(videoFullscreenManager->client() == &_videoFullscreenManagerProxyClient);
+            videoFullscreenManager->setClient(nullptr);
+        }
+    }
 }
 
 #pragma mark -
@@ -1141,6 +1110,13 @@
     return nullptr;
 }
 
+- (WebKit::VideoFullscreenManagerProxy*)_videoFullscreenManager
+{
+    if (auto page = [self._webView _page])
+        return page->videoFullscreenManager();
+    return nullptr;
+}
+
 - (void)_startToDismissFullscreenChanged:(id)sender
 {
     if (_inInteractiveDismiss)

Modified: trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.h (267052 => 267053)


--- trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.h	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.h	2020-09-14 22:39:50 UTC (rev 267053)
@@ -34,7 +34,6 @@
 namespace WebKit { 
 class LayerTreeContext;
 class WebPageProxy;
-class WKFullScreenWindowControllerVideoFullscreenModelClient;
 }
 
 namespace WebCore {
@@ -64,7 +63,6 @@
 
     double _savedScale;
     RefPtr<WebKit::VoidCallback> _repaintCallback;
-    std::unique_ptr<WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient> _videoFullscreenClient;
     float _savedTopContentInset;
 }
 
@@ -87,8 +85,6 @@
 - (void)beganExitFullScreenWithInitialFrame:(NSRect)initialFrame finalFrame:(NSRect)finalFrame;
 
 - (void)videoControlsManagerDidChange;
-- (void)didEnterPictureInPicture;
-- (void)didExitPictureInPicture;
 
 @end
 

Modified: trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm (267052 => 267053)


--- trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm	2020-09-14 22:39:19 UTC (rev 267052)
+++ trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm	2020-09-14 22:39:50 UTC (rev 267053)
@@ -24,11 +24,10 @@
  */
 
 #import "config.h"
+#import "WKFullScreenWindowController.h"
 
 #if ENABLE(FULLSCREEN_API) && !PLATFORM(IOS_FAMILY)
 
-#import "WKFullScreenWindowController.h"
-
 #import "AppKitSPI.h"
 #import "LayerTreeContext.h"
 #import "VideoFullscreenManagerProxy.h"
@@ -54,44 +53,32 @@
 
 static const NSTimeInterval DefaultWatchdogTimerInterval = 1;
 
-namespace WebKit {
+@interface WKFullScreenWindowController (VideoFullscreenManagerProxyClient)
+- (void)didEnterPictureInPicture;
+- (void)didExitPictureInPicture;
+@end
 
-class WKFullScreenWindowControllerVideoFullscreenModelClient : WebCore::VideoFullscreenModelClient {
+class WKFullScreenWindowControllerVideoFullscreenManagerProxyClient : public WebKit::VideoFullscreenManagerProxyClient {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     void setParent(WKFullScreenWindowController *parent) { m_parent = parent; }
 
-    void setInterface(WebCore::VideoFullscreenInterfaceMac* interface)
+private:
+    void fullscreenMayReturnToInline() final
     {
-        if (m_interface == interface)
-            return;
-
-        if (m_interface && m_interface->videoFullscreenModel())
-            m_interface->videoFullscreenModel()->removeClient(*this);
-        m_interface = interface;
-        if (m_interface && m_interface->videoFullscreenModel())
-            m_interface->videoFullscreenModel()->addClient(*this);
     }
 
-    WebCore::VideoFullscreenInterfaceMac* interface() const { return m_interface.get(); }
-
-    void didEnterPictureInPicture() final
+    void hasVideoInPictureInPictureDidChange(bool value) final
     {
-        [m_parent didEnterPictureInPicture];
+        if (value)
+            [m_parent didEnterPictureInPicture];
+        else
+            [m_parent didExitPictureInPicture];
     }
 
-    void didExitPictureInPicture() final
-    {
-        [m_parent didExitPictureInPicture];
-    }
-
-private:
     WKFullScreenWindowController *m_parent { nullptr };
-    RefPtr<WebCore::VideoFullscreenInterfaceMac> m_interface;
 };
 
-}
-
 enum FullScreenState : NSInteger {
     NotInFullScreen,
     WaitingToEnterFullScreen,
@@ -119,7 +106,9 @@
         [window makeFirstResponder:responder];
 }
 
-@implementation WKFullScreenWindowController
+@implementation WKFullScreenWindowController {
+    WKFullScreenWindowControllerVideoFullscreenManagerProxyClient _videoFullscreenManagerProxyClient;
+}
 
 #pragma mark -
 #pragma mark Initialization
@@ -155,8 +144,7 @@
     _webView = webView;
     _page = page.ptr();
 
-    _videoFullscreenClient = makeUnique<WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient>();
-    _videoFullscreenClient->setParent(self);
+    _videoFullscreenManagerProxyClient.setParent(self);
 
     [self videoControlsManagerDidChange];
 
@@ -178,8 +166,7 @@
         ASSERT(!_repaintCallback);
     }
 
-    _videoFullscreenClient->setParent(nil);
-    _videoFullscreenClient->setInterface(nullptr);
+    _videoFullscreenManagerProxyClient.setParent(nullptr);
 
     [super dealloc];
 }
@@ -655,10 +642,6 @@
 
 - (void)videoControlsManagerDidChange
 {
-    auto* videoFullscreenManager = _page ? _page->videoFullscreenManager() : nullptr;
-    auto* videoFullscreenInterface = videoFullscreenManager ? videoFullscreenManager->controlsManagerInterface() : nullptr;
-
-    _videoFullscreenClient->setInterface(videoFullscreenInterface);
 }
 
 - (void)didEnterPictureInPicture
@@ -668,7 +651,10 @@
 
 - (void)didExitPictureInPicture
 {
-    _videoFullscreenClient->setInterface(nullptr);
+    if (auto* videoFullscreenManager = self._videoFullscreenManager) {
+        ASSERT(videoFullscreenManager->client() == &_videoFullscreenManagerProxyClient);
+        videoFullscreenManager->setClient(nullptr);
+    }
 }
 
 #pragma mark -
@@ -702,6 +688,11 @@
 - (void)windowDidEnterFullScreen:(NSNotification *)notification
 {
     [self finishedEnterFullScreenAnimation:YES];
+
+    if (auto* videoFullscreenManager = self._videoFullscreenManager) {
+        ASSERT(videoFullscreenManager->client() == nullptr);
+        videoFullscreenManager->setClient(&_videoFullscreenManagerProxyClient);
+    }
 }
 
 - (void)windowDidFailToExitFullScreen:(NSWindow *)window
@@ -729,6 +720,14 @@
     return _page->fullScreenManager();
 }
 
+- (WebKit::VideoFullscreenManagerProxy*)_videoFullscreenManager
+{
+    if (!_page)
+        return nullptr;
+
+    return _page->videoFullscreenManager();
+}
+
 - (void)_replaceView:(NSView *)view with:(NSView *)otherView
 {
     [CATransaction begin];
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to