Changeset 267053 in webkit


Ignore:
Timestamp:
Sep 14, 2020 3:39:50 PM (4 years ago)
Author:
Peng Liu
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.

Location:
trunk/Source
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r267051 r267053  
     12020-09-14  Peng Liu  <peng.liu6@apple.com>
     2
     3        Returning to element fullscreen from PiP is not stable under stress tests
     4        https://bugs.webkit.org/show_bug.cgi?id=216287
     5
     6        Reviewed by Jer Noble.
     7
     8        * platform/cocoa/VideoFullscreenChangeObserver.h:
     9        Delete prepareToExitFullscreen().
     10
     11        * platform/ios/VideoFullscreenInterfaceAVKit.h:
     12        * platform/ios/VideoFullscreenInterfaceAVKit.mm:
     13        (VideoFullscreenInterfaceAVKit::VideoFullscreenInterfaceAVKit):
     14        (VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStop):
     15        (VideoFullscreenInterfaceAVKit::didStopPictureInPicture):
     16        (VideoFullscreenInterfaceAVKit::stopPictureInPictureTimerFired):
     17        (VideoFullscreenInterfaceAVKit::setReadyToStopPictureInPicture):
     18        VideoFullscreenInterfaceAVKit expects an element enters fullscreen and figure out the
     19        location and size of the video element after that, which will be used by AVKit for the
     20        exiting picture-in-picture animation. However, the entering fullscreen may take a long
     21        time and AVKit will start exiting picture-in-picture before the entering fullscreen
     22        transition is done. We need to add protection for such a scenario. This patch adds
     23        a timer (m_stopPictureInPictureTimer) for this purpose. This patch also makes sure
     24        VideoFullscreenInterfaceAVKit will call didExitPictureInPicture() properly.
     25
     26        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
     27        Delete prepareToExitFullscreen().
     28
     29        * platform/mac/VideoFullscreenInterfaceMac.mm:
     30        (WebCore::VideoFullscreenInterfaceMac::preparedToReturnToInline): This function
     31        is not used on Mac.
     32
    1332020-09-14  Sam Weinig  <weinig@apple.com>
    234
  • trunk/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h

    r266728 r267053  
    4242    virtual void didExitFullscreen() = 0;
    4343    virtual void didCleanupFullscreen() = 0;
    44     virtual void prepareToExitFullscreen() = 0;
    4544    virtual void fullscreenMayReturnToInline() = 0;
    4645    virtual void fullscreenWillReturnToInline() = 0;
  • trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h

    r266728 r267053  
    167167    void doEnterFullscreen();
    168168    void watchdogTimerFired();
     169    void stopPictureInPictureTimerFired();
    169170    WebAVPlayerController *playerController() const;
    170171
     
    184185    WTF::Function<void(bool)> m_prepareToInlineCallback;
    185186    RunLoop::Timer<VideoFullscreenInterfaceAVKit> m_watchdogTimer;
     187    RunLoop::Timer<VideoFullscreenInterfaceAVKit> m_stopPictureInPictureTimer;
    186188    FloatRect m_inlineRect;
    187189    RouteSharingPolicy m_routeSharingPolicy { RouteSharingPolicy::Default };
  • trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm

    r266728 r267053  
    8686
    8787static const Seconds defaultWatchdogTimerInterval { 1_s };
     88static const Seconds stopPictureInPictureTimerInterval { 1_s };
    8889static bool ignoreWatchdogForDebugging = false;
    8990
     
    813814    , m_playerViewControllerDelegate(adoptNS([[WebAVPlayerViewControllerDelegate alloc] init]))
    814815    , m_watchdogTimer(RunLoop::main(), this, &VideoFullscreenInterfaceAVKit::watchdogTimerFired)
     816    , m_stopPictureInPictureTimer(RunLoop::main(), this, &VideoFullscreenInterfaceAVKit::stopPictureInPictureTimerFired)
    815817{
    816818}
     
    10851087    if (m_fullscreenChangeObserver) {
    10861088        m_fullscreenChangeObserver->fullscreenMayReturnToInline();
    1087         m_fullscreenChangeObserver->prepareToExitFullscreen();
    10881089        if (m_readyToStopPictureInPicture)
    10891090            m_fullscreenChangeObserver->fullscreenWillReturnToInline();
     
    11771178        if (m_exitFullscreenNeedsExitPictureInPicture)
    11781179            doExitFullscreen();
     1180        else if (m_exitingPictureInPicture) {
     1181            m_exitingPictureInPicture = false;
     1182            if (m_videoFullscreenModel)
     1183                m_videoFullscreenModel->didExitPictureInPicture();
     1184        }
    11791185
    11801186        if (m_enterFullscreenNeedsExitPictureInPicture)
     
    11831189    }
    11841190
     1191    if (!m_readyToStopPictureInPicture) {
     1192        if (!m_stopPictureInPictureTimer.isActive())
     1193            m_stopPictureInPictureTimer.startOneShot(stopPictureInPictureTimerInterval);
     1194    } else
     1195        clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture);
     1196
    11851197    [m_playerLayerView setBackgroundColor:clearUIColor()];
    11861198    [[m_playerViewController view] setBackgroundColor:clearUIColor()];
    11871199
    1188     if (m_videoFullscreenModel)
    1189         m_videoFullscreenModel->requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenModeNone);
    1190 
    1191     clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture);
    1192 
    11931200    if (m_enterFullscreenNeedsExitPictureInPicture)
    11941201        doEnterFullscreen();
     
    11961203    if (m_exitFullscreenNeedsExitPictureInPicture)
    11971204        doExitFullscreen();
     1205    else if (m_exitingPictureInPicture) {
     1206        m_exitingPictureInPicture = false;
     1207
     1208        if (m_videoFullscreenModel)
     1209            m_videoFullscreenModel->didExitPictureInPicture();
     1210    }
    11981211}
    11991212
     
    15731586}
    15741587
     1588void VideoFullscreenInterfaceAVKit::stopPictureInPictureTimerFired()
     1589{
     1590    LOG(Fullscreen, "VideoFullscreenInterfaceAVKit::stopPictureInPictureTimerFired(%p) - not ready to stop picture-in-picture in %gs; forcing stop picture-in-picture.", this, stopPictureInPictureTimerInterval.value());
     1591    m_stopPictureInPictureTimer.stop();
     1592    clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture);
     1593}
     1594
    15751595void VideoFullscreenInterfaceAVKit::setMode(HTMLMediaElementEnums::VideoFullscreenMode mode)
    15761596{
     
    16061626
    16071627    m_readyToStopPictureInPicture = ready;
    1608     if (m_readyToStopPictureInPicture && m_fullscreenChangeObserver)
    1609         m_fullscreenChangeObserver->fullscreenWillReturnToInline();
     1628    if (m_readyToStopPictureInPicture) {
     1629        if (m_stopPictureInPictureTimer.isActive()) {
     1630            m_stopPictureInPictureTimer.stop();
     1631            clearMode(HTMLMediaElementEnums::VideoFullscreenModePictureInPicture);
     1632        }
     1633
     1634        if (m_fullscreenChangeObserver)
     1635            m_fullscreenChangeObserver->fullscreenWillReturnToInline();
     1636    }
    16101637}
    16111638
  • trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm

    r266728 r267053  
    129129    void didExitFullscreen() final;
    130130    void didCleanupFullscreen() final;
    131     void prepareToExitFullscreen() final { }
    132131    void fullscreenMayReturnToInline() final { }
    133132    void fullscreenWillReturnToInline() final;
  • trunk/Source/WebCore/platform/mac/VideoFullscreenInterfaceMac.mm

    r266728 r267053  
    553553void VideoFullscreenInterfaceMac::preparedToReturnToInline(bool visible, const IntRect& inlineRect, NSWindow *parentWindow)
    554554{
    555     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);
    556 
    557     if (!visible) {
    558         [m_webVideoFullscreenInterfaceObjC exitPIP];
    559         return;
    560     }
    561 
    562     ASSERT(parentWindow);
    563     [m_webVideoFullscreenInterfaceObjC exitPIPAnimatingToRect:(NSRect)inlineRect inWindow:parentWindow];
     555    UNUSED_PARAM(visible);
     556    UNUSED_PARAM(inlineRect);
     557    UNUSED_PARAM(parentWindow);
    564558}
    565559
  • trunk/Source/WebKit/ChangeLog

    r267042 r267053  
     12020-09-14  Peng Liu  <peng.liu6@apple.com>
     2
     3        Returning to element fullscreen from PiP is not stable under stress tests
     4        https://bugs.webkit.org/show_bug.cgi?id=216287
     5
     6        Reviewed by Jer Noble.
     7
     8        * UIProcess/Cocoa/VideoFullscreenManagerProxy.h:
     9        (WebKit::VideoFullscreenManagerProxyClient::~VideoFullscreenManagerProxyClient):
     10        (WebKit::VideoFullscreenManagerProxy::setClient):
     11        (WebKit::VideoFullscreenManagerProxy::client const):
     12        * UIProcess/Cocoa/VideoFullscreenManagerProxy.mm:
     13        (WebKit::VideoFullscreenModelContext::didEnterPictureInPicture):
     14        (WebKit::VideoFullscreenModelContext::didExitPictureInPicture):
     15        (WebKit::VideoFullscreenModelContext::willEnterPictureInPicture):
     16        (WebKit::VideoFullscreenManagerProxy::hasVideoInPictureInPictureDidChange):
     17        (WebKit::VideoFullscreenManagerProxy::fullscreenMayReturnToInline):
     18        (WebKit::VideoFullscreenModelContext::prepareToExitFullscreen): Deleted.
     19        Add the interface VideoFullscreenManagerProxyClient, which is used by WKFullScreenWindowController
     20        to implement the support of "returning to element fullscreen from PiP". Using VideoFullscreenModelClient
     21        for that purpose is not a good idea because the instance observed by VideoFullscreenModelClient may be
     22        destroyed when a video element is exiting picture-in-picture if we don't call
     23        VideoFullscreenManagerProxy::addClientForContext() and VideoFullscreenManagerProxy::removeClientForContext()
     24        properly.
     25
     26        * UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
     27        (-[WKFullScreenWindowController initWithWebView:]):
     28        (-[WKFullScreenWindowController dealloc]):
     29        (-[WKFullScreenWindowController beganEnterFullScreenWithInitialFrame:finalFrame:]):
     30        (-[WKFullScreenWindowController _completedExitFullScreen]):
     31        (-[WKFullScreenWindowController videoControlsManagerDidChange]):
     32        (-[WKFullScreenWindowController prepareToExitPictureInPicture]):
     33        (-[WKFullScreenWindowController didExitPictureInPicture]):
     34        (-[WKFullScreenWindowController _videoFullscreenManager]):
     35        (WKFullScreenWindowControllerVideoFullscreenModelClient::setParent): Deleted.
     36        (WKFullScreenWindowControllerVideoFullscreenModelClient::setInterface): Deleted.
     37        (WKFullScreenWindowControllerVideoFullscreenModelClient::interface const): Deleted.
     38        (-[WKFullScreenWindowController willEnterPictureInPicture]): Deleted.
     39        (-[WKFullScreenWindowController failedToEnterPictureInPicture]): Deleted.
     40        Use VideoFullscreenManagerProxyClient instead of VideoFullscreenModelClient to implement
     41        the support of "returning to element fullscreen from PiP" on iOS.
     42        A user can "return to element fullscreen from PiP" by clicking the "return to fullscreen"
     43        button on the PiP window, or by clicking the "fullscreen" button on the page. This patch
     44        adds support for the latter case.
     45
     46        * UIProcess/mac/WKFullScreenWindowController.h:
     47        * UIProcess/mac/WKFullScreenWindowController.mm:
     48        (-[WKFullScreenWindowController initWithWindow:webView:page:]):
     49        (-[WKFullScreenWindowController dealloc]):
     50        (-[WKFullScreenWindowController videoControlsManagerDidChange]):
     51        (-[WKFullScreenWindowController didExitPictureInPicture]):
     52        (-[WKFullScreenWindowController windowDidEnterFullScreen:]):
     53        (-[WKFullScreenWindowController _videoFullscreenManager]):
     54        (WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient::setParent): Deleted.
     55        (WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient::setInterface): Deleted.
     56        (WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient::interface const): Deleted.
     57        Use VideoFullscreenManagerProxyClient instead of VideoFullscreenModelClient to implement the
     58        support of "exiting fullscreen after entering PiP" on Mac. We may implement the support of
     59        "returning to element fullscreen from PiP" on Mac in the future.
     60
    1612020-09-14  Alex Christensen  <achristensen@webkit.org>
    262
  • trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h

    r266728 r267053  
    112112    void didExitFullscreen() final;
    113113    void didCleanupFullscreen() final;
    114     void prepareToExitFullscreen() final;
    115114    void fullscreenMayReturnToInline() final;
    116115    void fullscreenWillReturnToInline() final;
     
    125124};
    126125
     126class VideoFullscreenManagerProxyClient : public CanMakeWeakPtr<VideoFullscreenManagerProxyClient> {
     127public:
     128    virtual ~VideoFullscreenManagerProxyClient() { };
     129
     130    virtual void fullscreenMayReturnToInline() = 0;
     131    virtual void hasVideoInPictureInPictureDidChange(bool value) = 0;
     132};
     133
    127134class VideoFullscreenManagerProxy : public RefCounted<VideoFullscreenManagerProxy>, private IPC::MessageReceiver {
    128135public:
     
    145152
    146153    PlatformVideoFullscreenInterface* controlsManagerInterface();
     154    void setClient(VideoFullscreenManagerProxyClient* client) { m_client = makeWeakPtr(client); }
     155    VideoFullscreenManagerProxyClient* client() const { return m_client.get(); }
    147156
    148157    void forEachSession(Function<void(WebCore::VideoFullscreenModel&, PlatformVideoFullscreenInterface&)>&&);
     
    203212    PlaybackSessionContextIdentifier m_controlsManagerContextId;
    204213    HashMap<PlaybackSessionContextIdentifier, int> m_clientCounts;
     214    WeakPtr<VideoFullscreenManagerProxyClient> m_client;
    205215};
    206216
  • trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm

    r266728 r267053  
    289289}
    290290
    291 void VideoFullscreenModelContext::prepareToExitFullscreen()
    292 {
    293     for (auto& client : copyToVector(m_clients))
    294         client->prepareToExitPictureInPicture();
     291void VideoFullscreenModelContext::didEnterPictureInPicture()
     292{
     293    if (m_manager)
     294        m_manager->hasVideoInPictureInPictureDidChange(true);
     295}
     296
     297void VideoFullscreenModelContext::didExitPictureInPicture()
     298{
     299    if (m_manager)
     300        m_manager->hasVideoInPictureInPictureDidChange(false);
    295301}
    296302
     
    301307}
    302308
    303 void VideoFullscreenModelContext::didEnterPictureInPicture()
    304 {
    305     if (m_manager)
    306         m_manager->hasVideoInPictureInPictureDidChange(true);
    307 
    308     for (auto& client : copyToVector(m_clients))
    309         client->didEnterPictureInPicture();
    310 }
    311 
    312309void VideoFullscreenModelContext::failedToEnterPictureInPicture()
    313310{
     
    320317    for (auto& client : copyToVector(m_clients))
    321318        client->willExitPictureInPicture();
    322 }
    323 
    324 void VideoFullscreenModelContext::didExitPictureInPicture()
    325 {
    326     if (m_manager)
    327         m_manager->hasVideoInPictureInPictureDidChange(false);
    328 
    329     for (auto& client : copyToVector(m_clients))
    330         client->didExitPictureInPicture();
    331319}
    332320
     
    521509{
    522510    m_page->uiClient().hasVideoInPictureInPictureDidChange(m_page, value);
     511    if (m_client)
     512        m_client->hasVideoInPictureInPictureDidChange(value);
    523513}
    524514
     
    826816{
    827817    m_page->fullscreenMayReturnToInline();
     818    if (m_client)
     819        m_client->fullscreenMayReturnToInline();
    828820}
    829821
  • trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm

    r266728 r267053  
    2525
    2626#import "config.h"
     27#import "WKFullScreenWindowControllerIOS.h"
    2728
    2829#if PLATFORM(IOS_FAMILY) && ENABLE(FULLSCREEN_API)
    29 #import "WKFullScreenWindowControllerIOS.h"
    3030
    3131#import "UIKitSPI.h"
     
    428428#pragma mark -
    429429
    430 @interface WKFullScreenWindowController (VideoFullscreenClientCallbacks)
    431 - (void)willEnterPictureInPicture;
     430@interface WKFullScreenWindowController (VideoFullscreenManagerProxyClient)
    432431- (void)didEnterPictureInPicture;
    433 - (void)failedToEnterPictureInPicture;
    434432- (void)prepareToExitPictureInPicture;
    435433- (void)didExitPictureInPicture;
    436434@end
    437435
    438 class WKFullScreenWindowControllerVideoFullscreenModelClient : WebCore::VideoFullscreenModelClient {
     436class WKFullScreenWindowControllerVideoFullscreenManagerProxyClient : public WebKit::VideoFullscreenManagerProxyClient {
    439437    WTF_MAKE_FAST_ALLOCATED;
    440438public:
    441439    void setParent(WKFullScreenWindowController *parent) { m_parent = parent; }
    442440
    443     void setInterface(WebCore::VideoFullscreenInterfaceAVKit* interface)
    444     {
    445         if (m_interface == interface)
    446             return;
    447 
    448         if (m_interface && m_interface->videoFullscreenModel())
    449             m_interface->videoFullscreenModel()->removeClient(*this);
    450         m_interface = interface;
    451         if (m_interface && m_interface->videoFullscreenModel())
    452             m_interface->videoFullscreenModel()->addClient(*this);
    453     }
    454 
    455     WebCore::VideoFullscreenInterfaceAVKit* interface() const { return m_interface.get(); }
    456 
    457     void willEnterPictureInPicture() final
    458     {
    459         [m_parent willEnterPictureInPicture];
    460     }
    461 
    462     void didEnterPictureInPicture() final
    463     {
    464         [m_parent didEnterPictureInPicture];
    465     }
    466 
    467     void failedToEnterPictureInPicture() final
    468     {
    469         [m_parent failedToEnterPictureInPicture];
    470     }
    471 
    472     void prepareToExitPictureInPicture() final
     441private:
     442    void fullscreenMayReturnToInline() final
    473443    {
    474444        [m_parent prepareToExitPictureInPicture];
    475445    }
    476446
    477     void didExitPictureInPicture() final
     447    void hasVideoInPictureInPictureDidChange(bool value) final
    478448    {
    479         [m_parent didExitPictureInPicture];
    480     }
    481 
    482 private:
     449        if (value)
     450            [m_parent didEnterPictureInPicture];
     451        else
     452            [m_parent didExitPictureInPicture];
     453    }
     454
    483455    WKFullScreenWindowController *m_parent { nullptr };
    484     RefPtr<WebCore::VideoFullscreenInterfaceAVKit> m_interface;
    485456};
    486457
     
    504475    RetainPtr<WKFullScreenInteractiveTransition> _interactiveDismissTransitionCoordinator;
    505476
    506     WKFullScreenWindowControllerVideoFullscreenModelClient _videoFullscreenClient;
     477    WKFullScreenWindowControllerVideoFullscreenManagerProxyClient _videoFullscreenManagerProxyClient;
    507478    BOOL _inPictureInPicture;
     479    BOOL _enterFullscreenNeedsExitPictureInPicture;
    508480    BOOL _returnToFullscreenFromPictureInPicture;
    509481
     
    529501
    530502    self._webView = webView;
    531     _videoFullscreenClient.setParent(self);
     503    _videoFullscreenManagerProxyClient.setParent(self);
    532504
    533505    return self;
     
    539511    [[NSNotificationCenter defaultCenter] removeObserver:self];
    540512
    541     _videoFullscreenClient.setInterface(nullptr);
    542     _videoFullscreenClient.setParent(nullptr);
     513    _videoFullscreenManagerProxyClient.setParent(nullptr);
    543514
    544515    [super dealloc];
     
    726697            page->setSuppressVisibilityUpdates(false);
    727698
    728             auto* videoFullscreenManager = page->videoFullscreenManager();
    729             auto* videoFullscreenInterface = videoFullscreenManager ? videoFullscreenManager->controlsManagerInterface() : nullptr;
    730             if (_returnToFullscreenFromPictureInPicture) {
    731                 ASSERT(videoFullscreenInterface);
    732                 _returnToFullscreenFromPictureInPicture = NO;
    733                 if (videoFullscreenInterface)
    734                     videoFullscreenInterface->setReadyToStopPictureInPicture(YES);
    735             } else
    736                 _videoFullscreenClient.setInterface(videoFullscreenInterface);
     699            if (auto* videoFullscreenManager = self._videoFullscreenManager) {
     700                ASSERT(videoFullscreenManager->client() == nullptr);
     701                videoFullscreenManager->setClient(&_videoFullscreenManagerProxyClient);
     702                auto* videoFullscreenInterface = videoFullscreenManager ? videoFullscreenManager->controlsManagerInterface() : nullptr;
     703                if (videoFullscreenInterface) {
     704                    if (_returnToFullscreenFromPictureInPicture)
     705                        videoFullscreenInterface->setReadyToStopPictureInPicture(YES);
     706                    else if (_inPictureInPicture) {
     707                        if (auto* model = videoFullscreenInterface->videoFullscreenModel()) {
     708                            _enterFullscreenNeedsExitPictureInPicture = YES;
     709                            model->requestFullscreenMode(WebCore::HTMLMediaElementEnums::VideoFullscreenModeNone);
     710                        }
     711                    }
     712                }
     713            }
     714
     715            _returnToFullscreenFromPictureInPicture = NO;
    737716
    738717            return;
     
    851830    }
    852831
     832    if (!_inPictureInPicture) {
     833        if (auto* videoFullscreenManager = self._videoFullscreenManager) {
     834            ASSERT(videoFullscreenManager->client() == &_videoFullscreenManagerProxyClient);
     835            videoFullscreenManager->setClient(nullptr);
     836        }
     837    }
     838
    853839    [_window setHidden:YES];
    854840    _window = nil;
     
    868854            page->setNeedsDOMWindowResizeEvent();
    869855        }
    870 
    871         if (!_inPictureInPicture)
    872             _videoFullscreenClient.setInterface(nullptr);
    873856
    874857        _exitRequested = NO;
     
    905888    if (_fullscreenViewController)
    906889        [_fullscreenViewController videoControlsManagerDidChange];
    907 
    908     auto page = [self._webView _page];
    909     auto* videoFullscreenManager = page ? page->videoFullscreenManager() : nullptr;
    910     auto* videoFullscreenInterface = videoFullscreenManager ? videoFullscreenManager->controlsManagerInterface() : nullptr;
    911     _videoFullscreenClient.setInterface(videoFullscreenInterface);
    912890}
    913891
     
    923901}
    924902
    925 - (void)willEnterPictureInPicture
    926 {
    927     auto* interface = _videoFullscreenClient.interface();
    928     if (!interface || !interface->pictureInPictureWasStartedWhenEnteringBackground())
    929         return;
    930 
    931     [_fullscreenViewController setAnimatingViewAlpha:0];
    932 }
    933 
    934903- (void)didEnterPictureInPicture
    935904{
     
    938907}
    939908
    940 - (void)failedToEnterPictureInPicture
    941 {
    942     auto* interface = _videoFullscreenClient.interface();
    943     if (!interface || !interface->pictureInPictureWasStartedWhenEnteringBackground())
    944         return;
    945 
    946     [_fullscreenViewController setAnimatingViewAlpha:1];
    947 }
    948 
    949909- (void)prepareToExitPictureInPicture
    950910{
    951     auto* interface = _videoFullscreenClient.interface();
    952     if (!interface)
    953         return;
    954 
    955     interface->setReadyToStopPictureInPicture(NO);
     911    if (_enterFullscreenNeedsExitPictureInPicture)
     912        return;
     913
     914    auto* videoFullscreenInterface = self._videoFullscreenManager ? self._videoFullscreenManager->controlsManagerInterface() : nullptr;
     915
     916    if (!videoFullscreenInterface)
     917        return;
     918
     919    videoFullscreenInterface->setReadyToStopPictureInPicture(NO);
    956920    _returnToFullscreenFromPictureInPicture = YES;
    957921
     
    965929{
    966930    _inPictureInPicture = NO;
    967     if (!_returnToFullscreenFromPictureInPicture && ![self isFullScreen])
    968         _videoFullscreenClient.setInterface(nullptr);
     931    _enterFullscreenNeedsExitPictureInPicture = NO;
     932    if (![self isFullScreen]) {
     933        if (auto* videoFullscreenManager = self._videoFullscreenManager) {
     934            ASSERT(videoFullscreenManager->client() == &_videoFullscreenManagerProxyClient);
     935            videoFullscreenManager->setClient(nullptr);
     936        }
     937    }
    969938}
    970939
     
    11421111}
    11431112
     1113- (WebKit::VideoFullscreenManagerProxy*)_videoFullscreenManager
     1114{
     1115    if (auto page = [self._webView _page])
     1116        return page->videoFullscreenManager();
     1117    return nullptr;
     1118}
     1119
    11441120- (void)_startToDismissFullscreenChanged:(id)sender
    11451121{
  • trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.h

    r266728 r267053  
    3535class LayerTreeContext;
    3636class WebPageProxy;
    37 class WKFullScreenWindowControllerVideoFullscreenModelClient;
    3837}
    3938
     
    6564    double _savedScale;
    6665    RefPtr<WebKit::VoidCallback> _repaintCallback;
    67     std::unique_ptr<WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient> _videoFullscreenClient;
    6866    float _savedTopContentInset;
    6967}
     
    8886
    8987- (void)videoControlsManagerDidChange;
    90 - (void)didEnterPictureInPicture;
    91 - (void)didExitPictureInPicture;
    9288
    9389@end
  • trunk/Source/WebKit/UIProcess/mac/WKFullScreenWindowController.mm

    r266728 r267053  
    2525
    2626#import "config.h"
     27#import "WKFullScreenWindowController.h"
    2728
    2829#if ENABLE(FULLSCREEN_API) && !PLATFORM(IOS_FAMILY)
    29 
    30 #import "WKFullScreenWindowController.h"
    3130
    3231#import "AppKitSPI.h"
     
    5554static const NSTimeInterval DefaultWatchdogTimerInterval = 1;
    5655
    57 namespace WebKit {
    58 
    59 class WKFullScreenWindowControllerVideoFullscreenModelClient : WebCore::VideoFullscreenModelClient {
     56@interface WKFullScreenWindowController (VideoFullscreenManagerProxyClient)
     57- (void)didEnterPictureInPicture;
     58- (void)didExitPictureInPicture;
     59@end
     60
     61class WKFullScreenWindowControllerVideoFullscreenManagerProxyClient : public WebKit::VideoFullscreenManagerProxyClient {
    6062    WTF_MAKE_FAST_ALLOCATED;
    6163public:
    6264    void setParent(WKFullScreenWindowController *parent) { m_parent = parent; }
    6365
    64     void setInterface(WebCore::VideoFullscreenInterfaceMac* interface)
     66private:
     67    void fullscreenMayReturnToInline() final
    6568    {
    66         if (m_interface == interface)
    67             return;
    68 
    69         if (m_interface && m_interface->videoFullscreenModel())
    70             m_interface->videoFullscreenModel()->removeClient(*this);
    71         m_interface = interface;
    72         if (m_interface && m_interface->videoFullscreenModel())
    73             m_interface->videoFullscreenModel()->addClient(*this);
    74     }
    75 
    76     WebCore::VideoFullscreenInterfaceMac* interface() const { return m_interface.get(); }
    77 
    78     void didEnterPictureInPicture() final
     69    }
     70
     71    void hasVideoInPictureInPictureDidChange(bool value) final
    7972    {
    80         [m_parent didEnterPictureInPicture];
    81     }
    82 
    83     void didExitPictureInPicture() final
    84     {
    85         [m_parent didExitPictureInPicture];
    86     }
    87 
    88 private:
     73        if (value)
     74            [m_parent didEnterPictureInPicture];
     75        else
     76            [m_parent didExitPictureInPicture];
     77    }
     78
    8979    WKFullScreenWindowController *m_parent { nullptr };
    90     RefPtr<WebCore::VideoFullscreenInterfaceMac> m_interface;
    9180};
    92 
    93 }
    9481
    9582enum FullScreenState : NSInteger {
     
    120107}
    121108
    122 @implementation WKFullScreenWindowController
     109@implementation WKFullScreenWindowController {
     110    WKFullScreenWindowControllerVideoFullscreenManagerProxyClient _videoFullscreenManagerProxyClient;
     111}
    123112
    124113#pragma mark -
     
    156145    _page = page.ptr();
    157146
    158     _videoFullscreenClient = makeUnique<WebKit::WKFullScreenWindowControllerVideoFullscreenModelClient>();
    159     _videoFullscreenClient->setParent(self);
     147    _videoFullscreenManagerProxyClient.setParent(self);
    160148
    161149    [self videoControlsManagerDidChange];
     
    179167    }
    180168
    181     _videoFullscreenClient->setParent(nil);
    182     _videoFullscreenClient->setInterface(nullptr);
     169    _videoFullscreenManagerProxyClient.setParent(nullptr);
    183170
    184171    [super dealloc];
     
    656643- (void)videoControlsManagerDidChange
    657644{
    658     auto* videoFullscreenManager = _page ? _page->videoFullscreenManager() : nullptr;
    659     auto* videoFullscreenInterface = videoFullscreenManager ? videoFullscreenManager->controlsManagerInterface() : nullptr;
    660 
    661     _videoFullscreenClient->setInterface(videoFullscreenInterface);
    662645}
    663646
     
    669652- (void)didExitPictureInPicture
    670653{
    671     _videoFullscreenClient->setInterface(nullptr);
     654    if (auto* videoFullscreenManager = self._videoFullscreenManager) {
     655        ASSERT(videoFullscreenManager->client() == &_videoFullscreenManagerProxyClient);
     656        videoFullscreenManager->setClient(nullptr);
     657    }
    672658}
    673659
     
    703689{
    704690    [self finishedEnterFullScreenAnimation:YES];
     691
     692    if (auto* videoFullscreenManager = self._videoFullscreenManager) {
     693        ASSERT(videoFullscreenManager->client() == nullptr);
     694        videoFullscreenManager->setClient(&_videoFullscreenManagerProxyClient);
     695    }
    705696}
    706697
     
    728719        return nullptr;
    729720    return _page->fullScreenManager();
     721}
     722
     723- (WebKit::VideoFullscreenManagerProxy*)_videoFullscreenManager
     724{
     725    if (!_page)
     726        return nullptr;
     727
     728    return _page->videoFullscreenManager();
    730729}
    731730
Note: See TracChangeset for help on using the changeset viewer.