<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[265562] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/265562">265562</a></dd>
<dt>Author</dt> <dd>peng.liu6@apple.com</dd>
<dt>Date</dt> <dd>2020-08-12 13:55:35 -0700 (Wed, 12 Aug 2020)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add the support to return to element fullscreen from picture-in-picture
https://bugs.webkit.org/show_bug.cgi?id=215305

Reviewed by Jer Noble.

Source/WebCore:

When a container element enters fullscreen (with the fullscreen API), a descendant
video element will enter the video fullscreen standby state so that it can enter
picture-in-picture on application suspend (<a href="http://trac.webkit.org/projects/webkit/changeset/226217">r226217</a>). But we cannot restore
to that state from the picture-in-picture mode when we click the "restore" button
on the top-right corner of the PiP window. Instead, the video element will return
to the inline mode.

However, when a video element enters video fullscreen first and then enters
picture-in-picture, we can let the video restore to fullscreen by clicking the
"restore" button on the top-right corner of the picture-in-picture window.

The inconsistent behaviors may confuse users who are not aware of the difference
between the fullscreen API (or element fullscreen) and video fullscreen.

This patch enables the support to restore to element fullscreen from picture-in-picture
mode so that users can have a consistent experience on element fullscreen and
video fullscreen.

* dom/FullscreenManager.h:
Export requestFullscreenForElement() so that we can use it in WebKit code.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::enterFullscreen):
(WebCore::HTMLMediaElement::prepareForVideoFullscreenStandby):
* html/HTMLMediaElement.h:
* page/ChromeClient.h:
(WebCore::ChromeClient::prepareForVideoFullscreen):
Add the interface to request a video element to be prepared for the video fullscreen
standby state.

* platform/cocoa/VideoFullscreenChangeObserver.h:
Add prepareToExitFullscreen() and fullscreenWillReturnToInline().

* platform/cocoa/VideoFullscreenModel.h:
(WebCore::VideoFullscreenModelClient::hasVideoChanged):
(WebCore::VideoFullscreenModelClient::videoDimensionsChanged):
(WebCore::VideoFullscreenModelClient::prepareToExitPictureInPicture):
Some minor clean-ups and add function prepareToExitPictureInPicture().

* platform/ios/VideoFullscreenInterfaceAVKit.h:
* platform/ios/VideoFullscreenInterfaceAVKit.mm:
(VideoFullscreenInterfaceAVKit::cleanupFullscreen):
(VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStop):
(VideoFullscreenInterfaceAVKit::didStartPictureInPicture):
(VideoFullscreenInterfaceAVKit::willStopPictureInPicture):
(VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStopWithCompletionHandler):
(VideoFullscreenInterfaceAVKit::setReadyToStopPictureInPicture):
(VideoFullscreenInterfaceAVKit::willEnterStandbyFromPictureInPicture):
(VideoFullscreenInterfaceAVKit::setWillEnterStandbyFromPictureInPicture):
(VideoFullscreenInterfaceAVKit::fullscreenMayReturnToInline): Deleted.
When we enter picture-in-picture, we need to save the state and be prepared to
restore to element fullscreen if needed.

Before we exit picture-in-picture, if the "restore" button is clicked, we need
to notify the client to prepare for the picture-in-picture stop, and call
VideoFullscreenInterfaceAVKit::setReadyToStopPictureInPicture(true) when the client
is ready.

Based on those changes, a client (e.g., WKFullScreenWindowControllerVideoFullscreenModelClient)
can coordinate with WKFullScreenWindowController to implement the "restore to
element fullscreen" feature.

* platform/ios/WebVideoFullscreenControllerAVKit.mm:
(VideoFullscreenControllerContext::fullscreenWillReturnToInline):
(VideoFullscreenControllerContext::fullscreenMayReturnToInline): Deleted.

Source/WebKit:

This patch replaces WKFullScreenViewControllerVideoFullscreenModelClient
with WKFullScreenWindowControllerVideoFullscreenModelClient. We need to do
that because the instance of WKFullScreenViewControllerVideoFullscreenModelClient
will be destroyed after the container element exits fullscreen while the video
element enters picture-in-picture.

The instance of WKFullScreenWindowControllerVideoFullscreenModelClient
will always exist when the WKFullScreenWindowController instance is alive,
so that it can receive callbacks from the VideoFullscreenInterfaceAVKit instance
to implement the "return to element fullscreen from picture-in-picture" feature.

This patch supports the following transitions:
element fullscreen -> picture-in-picture (through user gestures)
element fullscreen -> picture-in-picture (through the PiP button)
picture-in-picture -> element fullscreen (when the tab is visible)
picture-in-picture -> element fullscreen (when the tab is invisible)
picture-in-picture -> element fullscreen (when the browser is in background)
picture-in-picture -> inline (when the browser is in foreground)
exit picture-in-picture when the browser is in background

* UIProcess/Cocoa/VideoFullscreenManagerProxy.h:
* UIProcess/Cocoa/VideoFullscreenManagerProxy.mm:
(WebKit::VideoFullscreenModelContext::fullscreenWillReturnToInline):
(WebKit::VideoFullscreenModelContext::prepareToExitFullscreen):
Notify clients to prepare for the stop of fullscreen/picture-in-picture.
(WebKit::VideoFullscreenManagerProxy::setupFullscreenWithID):
Fix issues that increase the client count unnecessarily.
(WebKit::VideoFullscreenManagerProxy::preparedToReturnToInline):
Call m_page->fullscreenMayReturnToInline() earlier.
(WebKit::VideoFullscreenManagerProxy::fullscreenMayReturnToInline):
Ditto.
(WebKit::VideoFullscreenManagerProxy::fullscreenWillReturnToInline):
Notify VideoFullscreenManager to prepare for exiting picture-in-picture or video fullscreen
and report the destination rectangle of the exit picture-in-picture or video fullscreen animations.

* UIProcess/WebFullScreenManagerProxy.cpp:
(WebKit::WebFullScreenManagerProxy::requestEnterFullScreen):
* UIProcess/WebFullScreenManagerProxy.h:
Add a function requestEnterFullScreen() so that we can request an element to enter fullscreen
from the UI process side.

* UIProcess/ios/fullscreen/WKFullScreenViewController.h:
* UIProcess/ios/fullscreen/WKFullScreenViewController.mm:
(-[WKFullScreenViewController initWithWebView:]):
(-[WKFullScreenViewController dealloc]):
(-[WKFullScreenViewController videoControlsManagerDidChange]):
(-[WKFullScreenViewController setAnimatingViewAlpha:]):
(-[WKFullScreenViewController _cancelAction:]):
(WKFullScreenViewControllerVideoFullscreenModelClient::setParent): Deleted.
(WKFullScreenViewControllerVideoFullscreenModelClient::setInterface): Deleted.
(WKFullScreenViewControllerVideoFullscreenModelClient::interface const): Deleted.
(-[WKFullScreenViewController willEnterPictureInPicture]): Deleted.
(-[WKFullScreenViewController didEnterPictureInPicture]): Deleted.
(-[WKFullScreenViewController failedToEnterPictureInPicture]): Deleted.
Minor clean-ups and remove code related to WKFullScreenViewControllerVideoFullscreenModelClient.

* UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.h:
* UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
(WKFullScreenWindowControllerVideoFullscreenModelClient::setParent):
(WKFullScreenWindowControllerVideoFullscreenModelClient::setInterface):
(WKFullScreenWindowControllerVideoFullscreenModelClient::interface const):
(-[WKFullScreenWindowController initWithWebView:]):
(-[WKFullScreenWindowController dealloc]):
(-[WKFullScreenWindowController enterFullScreen]):
(-[WKFullScreenWindowController beganEnterFullScreenWithInitialFrame:finalFrame:]):
(-[WKFullScreenWindowController requestEnterFullScreen]):
(-[WKFullScreenWindowController requestExitFullScreen]):
(-[WKFullScreenWindowController _completedExitFullScreen]):
(-[WKFullScreenWindowController videoControlsManagerDidChange]):
(-[WKFullScreenWindowController willEnterPictureInPicture]):
(-[WKFullScreenWindowController didEnterPictureInPicture]):
(-[WKFullScreenWindowController failedToEnterPictureInPicture]):
(-[WKFullScreenWindowController prepareToExitPictureInPicture]):
(-[WKFullScreenWindowController didExitPictureInPicture]):
Add WKFullScreenWindowControllerVideoFullscreenModelClient and implement the support
to "restore fullscreen from picture-in-picture".

* WebProcess/FullScreen/WebFullScreenManager.cpp:
(WebKit::WebFullScreenManager::enterFullScreenForElement):
(WebKit::WebFullScreenManager::requestEnterFullScreen):
* WebProcess/FullScreen/WebFullScreenManager.h:
* WebProcess/FullScreen/WebFullScreenManager.messages.in:
Add the interface requestEnterFullScreen() and the corresponding IPC message.

* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::prepareForVideoFullscreen):
* WebProcess/WebCoreSupport/WebChromeClient.h:
Add the interface to prepare for video fullscreen standby. The web process can
use this interface to create a VideoFullscreenManager instance to avoid the
scenario that an IPC message comes from the VideoFullscreenManagerProxy but
the VideoFullscreenManager instance is not constructed yet.

* WebProcess/cocoa/VideoFullscreenManager.h:
* WebProcess/cocoa/VideoFullscreenManager.messages.in:
* WebProcess/cocoa/VideoFullscreenManager.mm:
(WebKit::VideoFullscreenManager::fullscreenWillReturnToInline):
(WebKit::VideoFullscreenManager::fullscreenMayReturnToInline): Deleted.
Rename fullscreenMayReturnToInline() to fullscreenWillReturnToInline().
In the UI process side, fullscreenMayReturnToInline() is used by
VideoFullscreenManagerProxy to notify applications regarding UI
changes (e.g., switch browser tabs).</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomFullscreenManagerh">trunk/Source/WebCore/dom/FullscreenManager.h</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementcpp">trunk/Source/WebCore/html/HTMLMediaElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLMediaElementh">trunk/Source/WebCore/html/HTMLMediaElement.h</a></li>
<li><a href="#trunkSourceWebCorepageChromeClienth">trunk/Source/WebCore/page/ChromeClient.h</a></li>
<li><a href="#trunkSourceWebCoreplatformcocoaVideoFullscreenChangeObserverh">trunk/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h</a></li>
<li><a href="#trunkSourceWebCoreplatformcocoaVideoFullscreenModelh">trunk/Source/WebCore/platform/cocoa/VideoFullscreenModel.h</a></li>
<li><a href="#trunkSourceWebCoreplatformiosVideoFullscreenInterfaceAVKith">trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h</a></li>
<li><a href="#trunkSourceWebCoreplatformiosVideoFullscreenInterfaceAVKitmm">trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformiosWebVideoFullscreenControllerAVKitmm">trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitUIProcessCocoaVideoFullscreenManagerProxyh">trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessCocoaVideoFullscreenManagerProxymm">trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebFullScreenManagerProxycpp">trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.cpp</a></li>
<li><a href="#trunkSourceWebKitUIProcessWebFullScreenManagerProxyh">trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessiosfullscreenWKFullScreenViewControllerh">trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessiosfullscreenWKFullScreenViewControllermm">trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm</a></li>
<li><a href="#trunkSourceWebKitUIProcessiosfullscreenWKFullScreenWindowControllerIOSh">trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.h</a></li>
<li><a href="#trunkSourceWebKitUIProcessiosfullscreenWKFullScreenWindowControllerIOSmm">trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm</a></li>
<li><a href="#trunkSourceWebKitWebProcessFullScreenWebFullScreenManagercpp">trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.cpp</a></li>
<li><a href="#trunkSourceWebKitWebProcessFullScreenWebFullScreenManagerh">trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.h</a></li>
<li><a href="#trunkSourceWebKitWebProcessFullScreenWebFullScreenManagermessagesin">trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.messages.in</a></li>
<li><a href="#trunkSourceWebKitWebProcessWebCoreSupportWebChromeClientcpp">trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp</a></li>
<li><a href="#trunkSourceWebKitWebProcessWebCoreSupportWebChromeClienth">trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h</a></li>
<li><a href="#trunkSourceWebKitWebProcesscocoaVideoFullscreenManagerh">trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.h</a></li>
<li><a href="#trunkSourceWebKitWebProcesscocoaVideoFullscreenManagermessagesin">trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.messages.in</a></li>
<li><a href="#trunkSourceWebKitWebProcesscocoaVideoFullscreenManagermm">trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebCore/ChangeLog      2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -1,3 +1,76 @@
</span><ins>+2020-08-12  Peng Liu  <peng.liu6@apple.com>
+
+        Add the support to return to element fullscreen from picture-in-picture
+        https://bugs.webkit.org/show_bug.cgi?id=215305
+
+        Reviewed by Jer Noble.
+
+        When a container element enters fullscreen (with the fullscreen API), a descendant
+        video element will enter the video fullscreen standby state so that it can enter
+        picture-in-picture on application suspend (r226217). But we cannot restore
+        to that state from the picture-in-picture mode when we click the "restore" button
+        on the top-right corner of the PiP window. Instead, the video element will return
+        to the inline mode.
+
+        However, when a video element enters video fullscreen first and then enters
+        picture-in-picture, we can let the video restore to fullscreen by clicking the
+        "restore" button on the top-right corner of the picture-in-picture window.
+
+        The inconsistent behaviors may confuse users who are not aware of the difference
+        between the fullscreen API (or element fullscreen) and video fullscreen.
+
+        This patch enables the support to restore to element fullscreen from picture-in-picture
+        mode so that users can have a consistent experience on element fullscreen and
+        video fullscreen.
+
+        * dom/FullscreenManager.h:
+        Export requestFullscreenForElement() so that we can use it in WebKit code.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::enterFullscreen):
+        (WebCore::HTMLMediaElement::prepareForVideoFullscreenStandby):
+        * html/HTMLMediaElement.h:
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::prepareForVideoFullscreen):
+        Add the interface to request a video element to be prepared for the video fullscreen
+        standby state.
+
+        * platform/cocoa/VideoFullscreenChangeObserver.h:
+        Add prepareToExitFullscreen() and fullscreenWillReturnToInline().
+
+        * platform/cocoa/VideoFullscreenModel.h:
+        (WebCore::VideoFullscreenModelClient::hasVideoChanged):
+        (WebCore::VideoFullscreenModelClient::videoDimensionsChanged):
+        (WebCore::VideoFullscreenModelClient::prepareToExitPictureInPicture):
+        Some minor clean-ups and add function prepareToExitPictureInPicture().
+
+        * platform/ios/VideoFullscreenInterfaceAVKit.h:
+        * platform/ios/VideoFullscreenInterfaceAVKit.mm:
+        (VideoFullscreenInterfaceAVKit::cleanupFullscreen):
+        (VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStop):
+        (VideoFullscreenInterfaceAVKit::didStartPictureInPicture):
+        (VideoFullscreenInterfaceAVKit::willStopPictureInPicture):
+        (VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStopWithCompletionHandler):
+        (VideoFullscreenInterfaceAVKit::setReadyToStopPictureInPicture):
+        (VideoFullscreenInterfaceAVKit::willEnterStandbyFromPictureInPicture):
+        (VideoFullscreenInterfaceAVKit::setWillEnterStandbyFromPictureInPicture):
+        (VideoFullscreenInterfaceAVKit::fullscreenMayReturnToInline): Deleted.
+        When we enter picture-in-picture, we need to save the state and be prepared to
+        restore to element fullscreen if needed.
+
+        Before we exit picture-in-picture, if the "restore" button is clicked, we need
+        to notify the client to prepare for the picture-in-picture stop, and call
+        VideoFullscreenInterfaceAVKit::setReadyToStopPictureInPicture(true) when the client
+        is ready.
+
+        Based on those changes, a client (e.g., WKFullScreenWindowControllerVideoFullscreenModelClient)
+        can coordinate with WKFullScreenWindowController to implement the "restore to
+        element fullscreen" feature.
+
+        * platform/ios/WebVideoFullscreenControllerAVKit.mm:
+        (VideoFullscreenControllerContext::fullscreenWillReturnToInline):
+        (VideoFullscreenControllerContext::fullscreenMayReturnToInline): Deleted.
+
</ins><span class="cx"> 2020-08-12  Wenson Hsieh  <wenson_hsieh@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Broken formatting in price table on yandex.ru after translating to English
</span></span></pre></div>
<a id="trunkSourceWebCoredomFullscreenManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/FullscreenManager.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/FullscreenManager.h     2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebCore/dom/FullscreenManager.h        2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx">         EnforceIFrameAllowFullscreenRequirement,
</span><span class="cx">         ExemptIFrameAllowFullscreenRequirement,
</span><span class="cx">     };
</span><del>-    void requestFullscreenForElement(Element*, FullscreenCheckType);
</del><ins>+    WEBCORE_EXPORT void requestFullscreenForElement(Element*, FullscreenCheckType);
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void willEnterFullscreen(Element&);
</span><span class="cx">     WEBCORE_EXPORT void didEnterFullscreen();
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.cpp   2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp      2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -5956,7 +5956,7 @@
</span><span class="cx"> 
</span><span class="cx">     m_fullscreenTaskQueue.enqueueTask([this, mode] {
</span><span class="cx">         if (document().hidden()) {
</span><del>-            ALWAYS_LOG(LOGIDENTIFIER, "  returning because document is hidden");
</del><ins>+            ALWAYS_LOG(LOGIDENTIFIER, " returning because document is hidden");
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -6030,6 +6030,13 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void HTMLMediaElement::prepareForVideoFullscreenStandby()
+{
+#if ENABLE(VIDEO_PRESENTATION_MODE)
+    document().page()->chrome().client().prepareForVideoFullscreen();
+#endif
+}
+
</ins><span class="cx"> WEBCORE_EXPORT void HTMLMediaElement::setVideoFullscreenStandby(bool value)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(is<HTMLVideoElement>(*this));
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLMediaElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLMediaElement.h     2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h        2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -435,6 +435,7 @@
</span><span class="cx">     void enterFullscreen(VideoFullscreenMode);
</span><span class="cx">     WEBCORE_EXPORT void enterFullscreen() override;
</span><span class="cx">     WEBCORE_EXPORT void exitFullscreen();
</span><ins>+    WEBCORE_EXPORT void prepareForVideoFullscreenStandby();
</ins><span class="cx">     WEBCORE_EXPORT void setVideoFullscreenStandby(bool);
</span><span class="cx"> 
</span><span class="cx">     bool hasClosedCaptions() const override;
</span></span></pre></div>
<a id="trunkSourceWebCorepageChromeClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/ChromeClient.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/ChromeClient.h 2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebCore/page/ChromeClient.h    2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -355,6 +355,10 @@
</span><span class="cx">     virtual bool supportsVideoFullscreen(HTMLMediaElementEnums::VideoFullscreenMode) { return false; }
</span><span class="cx">     virtual bool supportsVideoFullscreenStandby() { return false; }
</span><span class="cx"> 
</span><ins>+#if ENABLE(VIDEO_PRESENTATION_MODE)
+    virtual void prepareForVideoFullscreen() { }
+#endif
+
</ins><span class="cx"> #if ENABLE(VIDEO)
</span><span class="cx">     virtual void enterVideoFullscreenForVideoElement(HTMLVideoElement&, HTMLMediaElementEnums::VideoFullscreenMode, bool standby) { UNUSED_PARAM(standby); }
</span><span class="cx">     virtual void setUpPlaybackControlsManager(HTMLMediaElement&) { }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcocoaVideoFullscreenChangeObserverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h      2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebCore/platform/cocoa/VideoFullscreenChangeObserver.h 2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -41,7 +41,9 @@
</span><span class="cx">     virtual void willExitFullscreen() = 0;
</span><span class="cx">     virtual void didExitFullscreen() = 0;
</span><span class="cx">     virtual void didCleanupFullscreen() = 0;
</span><ins>+    virtual void prepareToExitFullscreen() = 0;
</ins><span class="cx">     virtual void fullscreenMayReturnToInline() = 0;
</span><ins>+    virtual void fullscreenWillReturnToInline() = 0;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcocoaVideoFullscreenModelh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cocoa/VideoFullscreenModel.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/cocoa/VideoFullscreenModel.h       2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebCore/platform/cocoa/VideoFullscreenModel.h  2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -76,11 +76,12 @@
</span><span class="cx"> class VideoFullscreenModelClient {
</span><span class="cx"> public:
</span><span class="cx">     virtual ~VideoFullscreenModelClient() = default;
</span><del>-    virtual void hasVideoChanged(bool) { };
-    virtual void videoDimensionsChanged(const FloatSize&) { };
</del><ins>+    virtual void hasVideoChanged(bool) { }
+    virtual void videoDimensionsChanged(const FloatSize&) { }
</ins><span class="cx">     virtual void willEnterPictureInPicture() { }
</span><span class="cx">     virtual void didEnterPictureInPicture() { }
</span><span class="cx">     virtual void failedToEnterPictureInPicture() { }
</span><ins>+    virtual void prepareToExitPictureInPicture() { }
</ins><span class="cx">     virtual void willExitPictureInPicture() { }
</span><span class="cx">     virtual void didExitPictureInPicture() { }
</span><span class="cx">     virtual void modelDestroyed() { }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosVideoFullscreenInterfaceAVKith"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h        2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h   2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -133,7 +133,7 @@
</span><span class="cx">     HTMLMediaElementEnums::VideoFullscreenMode mode() const { return m_currentMode.mode(); }
</span><span class="cx">     bool allowsPictureInPicturePlayback() const { return m_allowsPictureInPicturePlayback; }
</span><span class="cx">     WEBCORE_EXPORT bool mayAutomaticallyShowVideoPictureInPicture() const;
</span><del>-    void fullscreenMayReturnToInline(WTF::Function<void(bool)>&& callback);
</del><ins>+    void prepareForPictureInPictureStop(WTF::Function<void(bool)>&& callback);
</ins><span class="cx">     bool wirelessVideoPlaybackDisabled() const;
</span><span class="cx">     WEBCORE_EXPORT void applicationDidBecomeActive();
</span><span class="cx"> 
</span><span class="lines">@@ -146,17 +146,18 @@
</span><span class="cx">     void exitFullscreenHandler(BOOL success, NSError *);
</span><span class="cx">     void enterFullscreenHandler(BOOL success, NSError *);
</span><span class="cx">     bool isPlayingVideoInEnhancedFullscreen() const;
</span><ins>+    WEBCORE_EXPORT void setReadyToStopPictureInPicture(BOOL);
+    WEBCORE_EXPORT bool willEnterStandbyFromPictureInPicture();
+    WEBCORE_EXPORT void setWillEnterStandbyFromPictureInPicture(BOOL);
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void setMode(HTMLMediaElementEnums::VideoFullscreenMode);
</span><span class="cx">     void clearMode(HTMLMediaElementEnums::VideoFullscreenMode);
</span><span class="cx">     bool hasMode(HTMLMediaElementEnums::VideoFullscreenMode mode) const { return m_currentMode.hasMode(mode); }
</span><span class="cx"> 
</span><del>-#if PLATFORM(IOS_FAMILY)
</del><span class="cx">     UIViewController *presentingViewController();
</span><span class="cx">     UIViewController *fullscreenViewController() const { return m_viewController.get(); }
</span><span class="cx">     WebAVPlayerLayerView* playerLayerView() const { return m_playerLayerView.get(); }
</span><span class="cx">     WEBCORE_EXPORT bool pictureInPictureWasStartedWhenEnteringBackground() const;
</span><del>-#endif
</del><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     WEBCORE_EXPORT VideoFullscreenInterfaceAVKit(PlaybackSessionInterfaceAVKit&);
</span><span class="lines">@@ -217,9 +218,14 @@
</span><span class="cx">     bool m_standby { false };
</span><span class="cx">     bool m_targetStandby { false };
</span><span class="cx"> 
</span><ins>+#if PLATFORM(WATCHOS)
</ins><span class="cx">     bool m_waitingForPreparedToExit { false };
</span><ins>+#endif
</ins><span class="cx">     bool m_shouldIgnoreAVKitCallbackAboutExitFullscreenReason { false };
</span><span class="cx">     bool m_enteringPictureInPicture { false };
</span><ins>+    bool m_exitingPictureInPicture { false };
+    bool m_readyToStopPictureInPicture { true };
+    bool m_willEnterStandbyFromPictureInPicture { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosVideoFullscreenInterfaceAVKitmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm       2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm  2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -969,14 +969,10 @@
</span><span class="cx">     
</span><span class="cx">     [m_playerViewController setDelegate:nil];
</span><span class="cx">     [m_playerViewController setPlayerController:nil];
</span><del>-    
-    if (m_currentMode.hasPictureInPicture()) {
</del><ins>+
+    if (m_currentMode.hasPictureInPicture())
</ins><span class="cx">         [m_playerViewController stopPictureInPicture];
</span><span class="cx"> 
</span><del>-        if (m_videoFullscreenModel)
-            m_videoFullscreenModel->didExitPictureInPicture();
-    }
-
</del><span class="cx">     if (m_currentMode.hasFullscreen()) {
</span><span class="cx">         [[m_playerViewController view] layoutIfNeeded];
</span><span class="cx">         [m_playerViewController exitFullScreenAnimated:NO completionHandler:[] (BOOL success, NSError* error) {
</span><span class="lines">@@ -1002,6 +998,13 @@
</span><span class="cx">     [playerController() setHasEnabledVideo:false];
</span><span class="cx">     [playerController() setHasVideo:false];
</span><span class="cx"> 
</span><ins>+    m_willEnterStandbyFromPictureInPicture = false;
+    if (m_exitingPictureInPicture) {
+        m_exitingPictureInPicture = false;
+        if (m_videoFullscreenModel)
+            m_videoFullscreenModel->didExitPictureInPicture();
+    }
+
</ins><span class="cx">     if (m_fullscreenChangeObserver)
</span><span class="cx">         m_fullscreenChangeObserver->didCleanupFullscreen();
</span><span class="cx"> }
</span><span class="lines">@@ -1066,11 +1069,15 @@
</span><span class="cx">     return [playerController() isPlaying] && (m_standby || m_currentMode.isFullscreen()) && supportsPictureInPicture();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void VideoFullscreenInterfaceAVKit::fullscreenMayReturnToInline(WTF::Function<void(bool)>&& callback)
</del><ins>+void VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStop(WTF::Function<void(bool)>&& callback)
</ins><span class="cx"> {
</span><span class="cx">     m_prepareToInlineCallback = WTFMove(callback);
</span><del>-    if (m_fullscreenChangeObserver)
</del><ins>+    if (m_fullscreenChangeObserver) {
</ins><span class="cx">         m_fullscreenChangeObserver->fullscreenMayReturnToInline();
</span><ins>+        m_fullscreenChangeObserver->prepareToExitFullscreen();
+        if (m_readyToStopPictureInPicture)
+            m_fullscreenChangeObserver->fullscreenWillReturnToInline();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void VideoFullscreenInterfaceAVKit::willStartPictureInPicture()
</span><span class="lines">@@ -1118,7 +1125,6 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_enteringPictureInPicture = false;
</span><del>-    m_standby = false;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void VideoFullscreenInterfaceAVKit::failedToStartPictureInPicture()
</span><span class="lines">@@ -1144,6 +1150,7 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(Fullscreen, "VideoFullscreenInterfaceAVKit::willStopPictureInPicture(%p)", this);
</span><span class="cx"> 
</span><ins>+    m_exitingPictureInPicture = true;
</ins><span class="cx">     m_shouldReturnToFullscreenWhenStoppingPiP = false;
</span><span class="cx"> 
</span><span class="cx">     if (m_currentMode.hasFullscreen() || m_restoringFullscreenForPictureInPictureStop)
</span><span class="lines">@@ -1190,6 +1197,7 @@
</span><span class="cx"> void VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStopWithCompletionHandler(void (^completionHandler)(BOOL restored))
</span><span class="cx"> {
</span><span class="cx">     LOG(Fullscreen, "VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStopWithCompletionHandler(%p)", this);
</span><ins>+
</ins><span class="cx">     if (m_shouldReturnToFullscreenWhenStoppingPiP) {
</span><span class="cx">         m_shouldReturnToFullscreenWhenStoppingPiP = false;
</span><span class="cx">         m_restoringFullscreenForPictureInPictureStop = true;
</span><span class="lines">@@ -1205,7 +1213,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    fullscreenMayReturnToInline([protectedThis = makeRefPtr(this), strongCompletionHandler = adoptNS([completionHandler copy])](bool restored)  {
</del><ins>+    prepareForPictureInPictureStop([protectedThis = makeRefPtr(this), strongCompletionHandler = adoptNS([completionHandler copy])](bool restored)  {
</ins><span class="cx">         LOG(Fullscreen, "VideoFullscreenInterfaceAVKit::prepareForPictureInPictureStopWithCompletionHandler lambda(%p) - restored(%s)", protectedThis.get(), boolString(restored));
</span><span class="cx">         ((void (^)(BOOL))strongCompletionHandler.get())(restored);
</span><span class="cx">     });
</span><span class="lines">@@ -1580,6 +1588,26 @@
</span><span class="cx">     return hasMode(WebCore::HTMLMediaElementEnums::VideoFullscreenModePictureInPicture) && [playerController() isPlaying];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void VideoFullscreenInterfaceAVKit::setReadyToStopPictureInPicture(BOOL ready)
+{
+    if (m_readyToStopPictureInPicture == ready)
+        return;
+
+    m_readyToStopPictureInPicture = ready;
+    if (m_readyToStopPictureInPicture && m_fullscreenChangeObserver)
+        m_fullscreenChangeObserver->fullscreenWillReturnToInline();
+}
+
+bool VideoFullscreenInterfaceAVKit::willEnterStandbyFromPictureInPicture()
+{
+    return m_willEnterStandbyFromPictureInPicture;
+}
+
+void VideoFullscreenInterfaceAVKit::setWillEnterStandbyFromPictureInPicture(BOOL value)
+{
+    m_willEnterStandbyFromPictureInPicture = value;
+}
+
</ins><span class="cx"> static Optional<bool> isPictureInPictureSupported;
</span><span class="cx"> 
</span><span class="cx"> void WebCore::setSupportsPictureInPicture(bool isSupported)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosWebVideoFullscreenControllerAVKitmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm   2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebCore/platform/ios/WebVideoFullscreenControllerAVKit.mm      2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -128,7 +128,9 @@
</span><span class="cx">     void willExitFullscreen() final;
</span><span class="cx">     void didExitFullscreen() final;
</span><span class="cx">     void didCleanupFullscreen() final;
</span><del>-    void fullscreenMayReturnToInline() final;
</del><ins>+    void prepareToExitFullscreen() final { }
+    void fullscreenMayReturnToInline() final { }
+    void fullscreenWillReturnToInline() final;
</ins><span class="cx"> 
</span><span class="cx">     // VideoFullscreenModelClient
</span><span class="cx">     void hasVideoChanged(bool) override;
</span><span class="lines">@@ -359,7 +361,7 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void VideoFullscreenControllerContext::fullscreenMayReturnToInline()
</del><ins>+void VideoFullscreenControllerContext::fullscreenWillReturnToInline()
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(isUIThread());
</span><span class="cx">     WebThreadRun([protectedThis = makeRefPtr(this), this] () mutable {
</span></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/ChangeLog       2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -1,3 +1,112 @@
</span><ins>+2020-08-12  Peng Liu  <peng.liu6@apple.com>
+
+        Add the support to return to element fullscreen from picture-in-picture
+        https://bugs.webkit.org/show_bug.cgi?id=215305
+
+        Reviewed by Jer Noble.
+
+        This patch replaces WKFullScreenViewControllerVideoFullscreenModelClient
+        with WKFullScreenWindowControllerVideoFullscreenModelClient. We need to do
+        that because the instance of WKFullScreenViewControllerVideoFullscreenModelClient
+        will be destroyed after the container element exits fullscreen while the video
+        element enters picture-in-picture.
+
+        The instance of WKFullScreenWindowControllerVideoFullscreenModelClient
+        will always exist when the WKFullScreenWindowController instance is alive,
+        so that it can receive callbacks from the VideoFullscreenInterfaceAVKit instance
+        to implement the "return to element fullscreen from picture-in-picture" feature.
+
+        This patch supports the following transitions:
+        element fullscreen -> picture-in-picture (through user gestures)
+        element fullscreen -> picture-in-picture (through the PiP button)
+        picture-in-picture -> element fullscreen (when the tab is visible)
+        picture-in-picture -> element fullscreen (when the tab is invisible)
+        picture-in-picture -> element fullscreen (when the browser is in background)
+        picture-in-picture -> inline (when the browser is in foreground)
+        exit picture-in-picture when the browser is in background
+
+        * UIProcess/Cocoa/VideoFullscreenManagerProxy.h:
+        * UIProcess/Cocoa/VideoFullscreenManagerProxy.mm:
+        (WebKit::VideoFullscreenModelContext::fullscreenWillReturnToInline):
+        (WebKit::VideoFullscreenModelContext::prepareToExitFullscreen):
+        Notify clients to prepare for the stop of fullscreen/picture-in-picture.
+        (WebKit::VideoFullscreenManagerProxy::setupFullscreenWithID):
+        Fix issues that increase the client count unnecessarily.
+        (WebKit::VideoFullscreenManagerProxy::preparedToReturnToInline):
+        Call m_page->fullscreenMayReturnToInline() earlier.
+        (WebKit::VideoFullscreenManagerProxy::fullscreenMayReturnToInline):
+        Ditto.
+        (WebKit::VideoFullscreenManagerProxy::fullscreenWillReturnToInline):
+        Notify VideoFullscreenManager to prepare for exiting picture-in-picture or video fullscreen
+        and report the destination rectangle of the exit picture-in-picture or video fullscreen animations.
+
+        * UIProcess/WebFullScreenManagerProxy.cpp:
+        (WebKit::WebFullScreenManagerProxy::requestEnterFullScreen):
+        * UIProcess/WebFullScreenManagerProxy.h:
+        Add a function requestEnterFullScreen() so that we can request an element to enter fullscreen
+        from the UI process side.
+
+        * UIProcess/ios/fullscreen/WKFullScreenViewController.h:
+        * UIProcess/ios/fullscreen/WKFullScreenViewController.mm:
+        (-[WKFullScreenViewController initWithWebView:]):
+        (-[WKFullScreenViewController dealloc]):
+        (-[WKFullScreenViewController videoControlsManagerDidChange]):
+        (-[WKFullScreenViewController setAnimatingViewAlpha:]):
+        (-[WKFullScreenViewController _cancelAction:]):
+        (WKFullScreenViewControllerVideoFullscreenModelClient::setParent): Deleted.
+        (WKFullScreenViewControllerVideoFullscreenModelClient::setInterface): Deleted.
+        (WKFullScreenViewControllerVideoFullscreenModelClient::interface const): Deleted.
+        (-[WKFullScreenViewController willEnterPictureInPicture]): Deleted.
+        (-[WKFullScreenViewController didEnterPictureInPicture]): Deleted.
+        (-[WKFullScreenViewController failedToEnterPictureInPicture]): Deleted.
+        Minor clean-ups and remove code related to WKFullScreenViewControllerVideoFullscreenModelClient.
+
+        * UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.h:
+        * UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
+        (WKFullScreenWindowControllerVideoFullscreenModelClient::setParent):
+        (WKFullScreenWindowControllerVideoFullscreenModelClient::setInterface):
+        (WKFullScreenWindowControllerVideoFullscreenModelClient::interface const):
+        (-[WKFullScreenWindowController initWithWebView:]):
+        (-[WKFullScreenWindowController dealloc]):
+        (-[WKFullScreenWindowController enterFullScreen]):
+        (-[WKFullScreenWindowController beganEnterFullScreenWithInitialFrame:finalFrame:]):
+        (-[WKFullScreenWindowController requestEnterFullScreen]):
+        (-[WKFullScreenWindowController requestExitFullScreen]):
+        (-[WKFullScreenWindowController _completedExitFullScreen]):
+        (-[WKFullScreenWindowController videoControlsManagerDidChange]):
+        (-[WKFullScreenWindowController willEnterPictureInPicture]):
+        (-[WKFullScreenWindowController didEnterPictureInPicture]):
+        (-[WKFullScreenWindowController failedToEnterPictureInPicture]):
+        (-[WKFullScreenWindowController prepareToExitPictureInPicture]):
+        (-[WKFullScreenWindowController didExitPictureInPicture]):
+        Add WKFullScreenWindowControllerVideoFullscreenModelClient and implement the support
+        to "restore fullscreen from picture-in-picture".
+
+        * WebProcess/FullScreen/WebFullScreenManager.cpp:
+        (WebKit::WebFullScreenManager::enterFullScreenForElement):
+        (WebKit::WebFullScreenManager::requestEnterFullScreen):
+        * WebProcess/FullScreen/WebFullScreenManager.h:
+        * WebProcess/FullScreen/WebFullScreenManager.messages.in:
+        Add the interface requestEnterFullScreen() and the corresponding IPC message.
+
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::prepareForVideoFullscreen):
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        Add the interface to prepare for video fullscreen standby. The web process can
+        use this interface to create a VideoFullscreenManager instance to avoid the
+        scenario that an IPC message comes from the VideoFullscreenManagerProxy but
+        the VideoFullscreenManager instance is not constructed yet.
+
+        * WebProcess/cocoa/VideoFullscreenManager.h:
+        * WebProcess/cocoa/VideoFullscreenManager.messages.in:
+        * WebProcess/cocoa/VideoFullscreenManager.mm:
+        (WebKit::VideoFullscreenManager::fullscreenWillReturnToInline):
+        (WebKit::VideoFullscreenManager::fullscreenMayReturnToInline): Deleted.
+        Rename fullscreenMayReturnToInline() to fullscreenWillReturnToInline().
+        In the UI process side, fullscreenMayReturnToInline() is used by
+        VideoFullscreenManagerProxy to notify applications regarding UI
+        changes (e.g., switch browser tabs).
+
</ins><span class="cx"> 2020-08-12  Wenson Hsieh  <wenson_hsieh@apple.com>
</span><span class="cx"> 
</span><span class="cx">         WebPageProxy::registerEditCommand should be robust against invalid undo step identifiers
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessCocoaVideoFullscreenManagerProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h        2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h   2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -111,7 +111,9 @@
</span><span class="cx">     void willExitFullscreen() final;
</span><span class="cx">     void didExitFullscreen() final;
</span><span class="cx">     void didCleanupFullscreen() final;
</span><ins>+    void prepareToExitFullscreen() final;
</ins><span class="cx">     void fullscreenMayReturnToInline() final;
</span><ins>+    void fullscreenWillReturnToInline() final;
</ins><span class="cx"> 
</span><span class="cx">     VideoFullscreenManagerProxy* m_manager;
</span><span class="cx">     Ref<PlaybackSessionModelContext> m_playbackSessionModel;
</span><span class="lines">@@ -189,6 +191,7 @@
</span><span class="cx">     void setVideoLayerGravity(PlaybackSessionContextIdentifier, WebCore::MediaPlayerEnums::VideoGravity);
</span><span class="cx">     void fullscreenModeChanged(PlaybackSessionContextIdentifier, WebCore::HTMLMediaElementEnums::VideoFullscreenMode);
</span><span class="cx">     void fullscreenMayReturnToInline(PlaybackSessionContextIdentifier);
</span><ins>+    void fullscreenWillReturnToInline(PlaybackSessionContextIdentifier);
</ins><span class="cx"> 
</span><span class="cx">     bool m_mockVideoPresentationModeEnabled { false };
</span><span class="cx">     WebCore::FloatSize m_mockPictureInPictureWindowSize { DefaultMockPictureInPictureWindowWidth, DefaultMockPictureInPictureWindowHeight };
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessCocoaVideoFullscreenManagerProxymm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm       2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm  2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -274,6 +274,12 @@
</span><span class="cx">         m_manager->fullscreenMayReturnToInline(m_contextId);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void VideoFullscreenModelContext::fullscreenWillReturnToInline()
+{
+    if (m_manager)
+        m_manager->fullscreenWillReturnToInline(m_contextId);
+}
+
</ins><span class="cx"> void VideoFullscreenModelContext::requestRouteSharingPolicyAndContextUID(CompletionHandler<void(WebCore::RouteSharingPolicy, String)>&& completionHandler)
</span><span class="cx"> {
</span><span class="cx">     if (m_manager)
</span><span class="lines">@@ -282,6 +288,12 @@
</span><span class="cx">         completionHandler(WebCore::RouteSharingPolicy::Default, emptyString());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void VideoFullscreenModelContext::prepareToExitFullscreen()
+{
+    for (auto& client : m_clients)
+        client->prepareToExitPictureInPicture();
+}
+
</ins><span class="cx"> void VideoFullscreenModelContext::willEnterPictureInPicture()
</span><span class="cx"> {
</span><span class="cx">     for (auto& client : m_clients)
</span><span class="lines">@@ -512,7 +524,12 @@
</span><span class="cx">     MESSAGE_CHECK(videoLayerID);
</span><span class="cx"> 
</span><span class="cx">     auto& [model, interface] = ensureModelAndInterface(contextId);
</span><del>-    addClientForContext(contextId);
</del><ins>+#if PLATFORM(IOS_FAMILY)
+    if (interface->willEnterStandbyFromPictureInPicture())
+        interface->setWillEnterStandbyFromPictureInPicture(NO);
+    else if (videoFullscreenMode != HTMLMediaElementEnums::VideoFullscreenModePictureInPicture || !standby)
+        addClientForContext(contextId);
+#endif
</ins><span class="cx"> 
</span><span class="cx">     if (m_mockVideoPresentationModeEnabled) {
</span><span class="cx">         if (!videoDimensions.isEmpty())
</span><span class="lines">@@ -696,8 +713,6 @@
</span><span class="cx"> 
</span><span class="cx"> void VideoFullscreenManagerProxy::preparedToReturnToInline(PlaybackSessionContextIdentifier contextId, bool visible, WebCore::IntRect inlineRect)
</span><span class="cx"> {
</span><del>-    m_page->fullscreenMayReturnToInline();
-
</del><span class="cx"> #if !PLATFORM(IOS_FAMILY)
</span><span class="cx">     IntRect inlineWindowRect;
</span><span class="cx">     m_page->rootViewToWindow(inlineRect, inlineWindowRect);
</span><span class="lines">@@ -806,8 +821,13 @@
</span><span class="cx"> 
</span><span class="cx"> void VideoFullscreenManagerProxy::fullscreenMayReturnToInline(PlaybackSessionContextIdentifier contextId)
</span><span class="cx"> {
</span><ins>+    m_page->fullscreenMayReturnToInline();
+}
+
+void VideoFullscreenManagerProxy::fullscreenWillReturnToInline(PlaybackSessionContextIdentifier contextId)
+{
</ins><span class="cx">     bool isViewVisible = m_page->isViewVisible();
</span><del>-    m_page->send(Messages::VideoFullscreenManager::FullscreenMayReturnToInline(contextId, isViewVisible));
</del><ins>+    m_page->send(Messages::VideoFullscreenManager::FullscreenWillReturnToInline(contextId, isViewVisible));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebFullScreenManagerProxycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.cpp (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.cpp      2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.cpp 2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -92,6 +92,11 @@
</span><span class="cx">     m_page.send(Messages::WebFullScreenManager::SetAnimatingFullScreen(animating));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebFullScreenManagerProxy::requestEnterFullScreen()
+{
+    m_page.send(Messages::WebFullScreenManager::RequestEnterFullScreen());
+}
+
</ins><span class="cx"> void WebFullScreenManagerProxy::requestExitFullScreen()
</span><span class="cx"> {
</span><span class="cx">     m_page.send(Messages::WebFullScreenManager::RequestExitFullScreen());
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessWebFullScreenManagerProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.h        2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.h   2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -69,6 +69,7 @@
</span><span class="cx">     void willExitFullScreen();
</span><span class="cx">     void didExitFullScreen();
</span><span class="cx">     void setAnimatingFullScreen(bool);
</span><ins>+    void requestEnterFullScreen();
</ins><span class="cx">     void requestExitFullScreen();
</span><span class="cx">     void saveScrollPosition();
</span><span class="cx">     void restoreScrollPosition();
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessiosfullscreenWKFullScreenViewControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.h        2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.h   2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx"> 
</span><span class="cx"> @interface WKFullScreenViewController : UIViewController
</span><span class="cx"> @property (retain, nonatomic) id target;
</span><del>-@property (assign, nonatomic) SEL action;
</del><ins>+@property (assign, nonatomic) SEL exitFullScreenAction;
</ins><span class="cx"> @property (copy, nonatomic) NSString *location;
</span><span class="cx"> @property (assign, nonatomic) BOOL prefersStatusBarHidden;
</span><span class="cx"> @property (assign, nonatomic) BOOL prefersHomeIndicatorAutoHidden;
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> - (void)showUI;
</span><span class="cx"> - (void)hideUI;
</span><span class="cx"> - (void)videoControlsManagerDidChange;
</span><ins>+- (void)setAnimatingViewAlpha:(CGFloat)alpha;
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> NS_ASSUME_NONNULL_END
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessiosfullscreenWKFullScreenViewControllermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm       2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenViewController.mm  2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -46,12 +46,6 @@
</span><span class="cx"> 
</span><span class="cx"> @class WKFullscreenStackView;
</span><span class="cx"> 
</span><del>-@interface WKFullScreenViewController (VideoFullscreenClientCallbacks)
-- (void)willEnterPictureInPicture;
-- (void)didEnterPictureInPicture;
-- (void)failedToEnterPictureInPicture;
-@end
-
</del><span class="cx"> class WKFullScreenViewControllerPlaybackSessionModelClient : WebCore::PlaybackSessionModelClient {
</span><span class="cx"> public:
</span><span class="cx">     void setParent(WKFullScreenViewController *parent) { m_parent = parent; }
</span><span class="lines">@@ -87,45 +81,6 @@
</span><span class="cx">     RefPtr<WebCore::PlaybackSessionInterfaceAVKit> m_interface;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-class WKFullScreenViewControllerVideoFullscreenModelClient : WebCore::VideoFullscreenModelClient {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    void setParent(WKFullScreenViewController *parent) { m_parent = parent; }
-
-    void setInterface(WebCore::VideoFullscreenInterfaceAVKit* interface)
-    {
-        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];
-    }
-
-private:
-    WKFullScreenViewController *m_parent { nullptr };
-    RefPtr<WebCore::VideoFullscreenInterfaceAVKit> m_interface;
-};
-
</del><span class="cx"> #pragma mark - _WKExtrinsicButton
</span><span class="cx"> 
</span><span class="cx"> @interface _WKExtrinsicButton : UIButton
</span><span class="lines">@@ -164,7 +119,6 @@
</span><span class="cx">     RetainPtr<NSLayoutConstraint> _topConstraint;
</span><span class="cx">     WebKit::FullscreenTouchSecheuristic _secheuristic;
</span><span class="cx">     WKFullScreenViewControllerPlaybackSessionModelClient _playbackClient;
</span><del>-    WKFullScreenViewControllerVideoFullscreenModelClient _videoFullscreenClient;
</del><span class="cx">     CGFloat _nonZeroStatusBarHeight;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -188,7 +142,6 @@
</span><span class="cx">     self._webView = webView;
</span><span class="cx"> 
</span><span class="cx">     _playbackClient.setParent(self);
</span><del>-    _videoFullscreenClient.setParent(self);
</del><span class="cx"> 
</span><span class="cx">     return self;
</span><span class="cx"> }
</span><span class="lines">@@ -200,8 +153,6 @@
</span><span class="cx"> 
</span><span class="cx">     _playbackClient.setParent(nullptr);
</span><span class="cx">     _playbackClient.setInterface(nullptr);
</span><del>-    _videoFullscreenClient.setParent(nullptr);
-    _videoFullscreenClient.setInterface(nullptr);
</del><span class="cx"> 
</span><span class="cx">     [_target release];
</span><span class="cx">     [_location release];
</span><span class="lines">@@ -261,7 +212,6 @@
</span><span class="cx">     auto* playbackSessionInterface = videoFullscreenInterface ? &videoFullscreenInterface->playbackSessionInterface() : nullptr;
</span><span class="cx"> 
</span><span class="cx">     _playbackClient.setInterface(playbackSessionInterface);
</span><del>-    _videoFullscreenClient.setInterface(videoFullscreenInterface);
</del><span class="cx"> 
</span><span class="cx">     WebCore::PlaybackSessionModel* playbackSessionModel = playbackSessionInterface ? playbackSessionInterface->playbackSessionModel() : nullptr;
</span><span class="cx">     self.playing = playbackSessionModel ? playbackSessionModel->isPlaying() : NO;
</span><span class="lines">@@ -272,6 +222,13 @@
</span><span class="cx">     [_pipButton setHidden:!isPiPEnabled || !isPiPSupported];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)setAnimatingViewAlpha:(CGFloat)alpha
+{
+    [UIView animateWithDuration:pipHideAnimationDuration animations:^{
+        _animatingView.get().alpha = alpha;
+    }];
+}
+
</ins><span class="cx"> - (void)setPrefersStatusBarHidden:(BOOL)value
</span><span class="cx"> {
</span><span class="cx">     _prefersStatusBarHidden = value;
</span><span class="lines">@@ -330,33 +287,6 @@
</span><span class="cx">         [self showUI];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)willEnterPictureInPicture
-{
-    auto* interface = _videoFullscreenClient.interface();
-    if (!interface || !interface->pictureInPictureWasStartedWhenEnteringBackground())
-        return;
-
-    [UIView animateWithDuration:pipHideAnimationDuration animations:^{
-        _animatingView.get().alpha = 0;
-    }];
-}
-
-- (void)didEnterPictureInPicture
-{
-    [self _cancelAction:self];
-}
-
-- (void)failedToEnterPictureInPicture
-{
-    auto* interface = _videoFullscreenClient.interface();
-    if (!interface || !interface->pictureInPictureWasStartedWhenEnteringBackground())
-        return;
-
-    [UIView animateWithDuration:pipHideAnimationDuration animations:^{
-        _animatingView.get().alpha = 1;
-    }];
-}
-
</del><span class="cx"> #pragma mark - UIViewController Overrides
</span><span class="cx"> 
</span><span class="cx"> - (void)loadView
</span><span class="lines">@@ -503,7 +433,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)_cancelAction:(id)sender
</span><span class="cx"> {
</span><del>-    [[self target] performSelector:[self action]];
</del><ins>+    [[self target] performSelector:[self exitFullScreenAction]];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_togglePiPAction:(id)sender
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessiosfullscreenWKFullScreenWindowControllerIOSh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.h   2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.h      2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> - (id)initWithWebView:(WKWebView *)webView;
</span><span class="cx"> - (void)enterFullScreen;
</span><span class="cx"> - (void)beganEnterFullScreenWithInitialFrame:(CGRect)initialFrame finalFrame:(CGRect)finalFrame;
</span><ins>+- (void)requestEnterFullScreen;
</ins><span class="cx"> - (void)requestExitFullScreen;
</span><span class="cx"> - (void)exitFullScreen;
</span><span class="cx"> - (void)beganExitFullScreenWithInitialFrame:(CGRect)initialFrame finalFrame:(CGRect)finalFrame;
</span></span></pre></div>
<a id="trunkSourceWebKitUIProcessiosfullscreenWKFullScreenWindowControllerIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm  2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm     2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -424,6 +424,65 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma mark -
</span><span class="cx"> 
</span><ins>+@interface WKFullScreenWindowController (VideoFullscreenClientCallbacks)
+- (void)willEnterPictureInPicture;
+- (void)didEnterPictureInPicture;
+- (void)failedToEnterPictureInPicture;
+- (void)prepareToExitPictureInPicture;
+- (void)didExitPictureInPicture;
+@end
+
+class WKFullScreenWindowControllerVideoFullscreenModelClient : WebCore::VideoFullscreenModelClient {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    void setParent(WKFullScreenWindowController *parent) { m_parent = parent; }
+
+    void setInterface(WebCore::VideoFullscreenInterfaceAVKit* interface)
+    {
+        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
+    {
+        [m_parent didExitPictureInPicture];
+    }
+
+private:
+    WKFullScreenWindowController *m_parent { nullptr };
+    RefPtr<WebCore::VideoFullscreenInterfaceAVKit> m_interface;
+};
+
+#pragma mark -
+
</ins><span class="cx"> @implementation WKFullScreenWindowController {
</span><span class="cx">     RetainPtr<WKFullScreenPlaceholderView> _webViewPlaceholder;
</span><span class="cx"> 
</span><span class="lines">@@ -441,6 +500,10 @@
</span><span class="cx">     RetainPtr<UIPinchGestureRecognizer> _interactivePinchDismissGestureRecognizer;
</span><span class="cx">     RetainPtr<WKFullScreenInteractiveTransition> _interactiveDismissTransitionCoordinator;
</span><span class="cx"> 
</span><ins>+    WKFullScreenWindowControllerVideoFullscreenModelClient _videoFullscreenClient;
+    BOOL _inPictureInPicture;
+    BOOL _returnToFullscreenFromPictureInPicture;
+
</ins><span class="cx">     CGRect _initialFrame;
</span><span class="cx">     CGRect _finalFrame;
</span><span class="cx"> 
</span><span class="lines">@@ -448,6 +511,8 @@
</span><span class="cx">     BOOL _EVOrganizationNameIsValid;
</span><span class="cx">     BOOL _inInteractiveDismiss;
</span><span class="cx">     BOOL _exitRequested;
</span><ins>+    BOOL _enterRequested;
+    BOOL _exitingFullScreen;
</ins><span class="cx"> 
</span><span class="cx">     RetainPtr<id> _notificationListener;
</span><span class="cx"> }
</span><span class="lines">@@ -460,6 +525,7 @@
</span><span class="cx">         return nil;
</span><span class="cx"> 
</span><span class="cx">     self._webView = webView;
</span><ins>+    _videoFullscreenClient.setParent(self);
</ins><span class="cx"> 
</span><span class="cx">     return self;
</span><span class="cx"> }
</span><span class="lines">@@ -469,6 +535,9 @@
</span><span class="cx">     [NSObject cancelPreviousPerformRequestsWithTarget:self];
</span><span class="cx">     [[NSNotificationCenter defaultCenter] removeObserver:self];
</span><span class="cx"> 
</span><ins>+    _videoFullscreenClient.setInterface(nullptr);
+    _videoFullscreenClient.setParent(nullptr);
+
</ins><span class="cx">     [super dealloc];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -524,7 +593,7 @@
</span><span class="cx">     [_fullscreenViewController setTransitioningDelegate:self];
</span><span class="cx">     [_fullscreenViewController setModalPresentationCapturesStatusBarAppearance:YES];
</span><span class="cx">     [_fullscreenViewController setTarget:self];
</span><del>-    [_fullscreenViewController setAction:@selector(requestExitFullScreen)];
</del><ins>+    [_fullscreenViewController setExitFullScreenAction:@selector(requestExitFullScreen)];
</ins><span class="cx">     _fullscreenViewController.get().view.frame = _rootViewController.get().view.bounds;
</span><span class="cx">     [self _updateLocationInfo];
</span><span class="cx"> 
</span><span class="lines">@@ -652,6 +721,17 @@
</span><span class="cx">             manager->didEnterFullScreen();
</span><span class="cx">             manager->setAnimatingFullScreen(false);
</span><span class="cx">             page->setSuppressVisibilityUpdates(false);
</span><ins>+
+            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);
+
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -660,6 +740,19 @@
</span><span class="cx">     }];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)requestEnterFullScreen
+{
+    if (_fullScreenState != WebKit::NotInFullScreen)
+        return;
+
+    if (auto* manager = self._manager) {
+        manager->requestEnterFullScreen();
+        return;
+    }
+
+    ASSERT_NOT_REACHED();
+}
+
</ins><span class="cx"> - (void)requestExitFullScreen
</span><span class="cx"> {
</span><span class="cx">     if (_fullScreenState != WebKit::InFullScreen) {
</span><span class="lines">@@ -669,6 +762,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (auto* manager = self._manager) {
</span><span class="cx">         manager->requestExitFullScreen();
</span><ins>+        _exitingFullScreen = YES;
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -770,6 +864,16 @@
</span><span class="cx">             page->setSuppressVisibilityUpdates(false);
</span><span class="cx">             page->setNeedsDOMWindowResizeEvent();
</span><span class="cx">         }
</span><ins>+
+        if (!_inPictureInPicture)
+            _videoFullscreenClient.setInterface(nullptr);
+
+        _exitRequested = NO;
+        _exitingFullScreen = NO;
+        if (_enterRequested) {
+            _enterRequested = NO;
+            [self requestEnterFullScreen];
+        }
</ins><span class="cx">     });
</span><span class="cx"> 
</span><span class="cx">     if (auto page = [self._webView _page])
</span><span class="lines">@@ -779,7 +883,6 @@
</span><span class="cx"> 
</span><span class="cx">     [_fullscreenViewController setPrefersStatusBarHidden:YES];
</span><span class="cx">     _fullscreenViewController = nil;
</span><del>-    _exitRequested = NO;
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)close
</span><span class="lines">@@ -798,6 +901,11 @@
</span><span class="cx"> {
</span><span class="cx">     if (_fullscreenViewController)
</span><span class="cx">         [_fullscreenViewController videoControlsManagerDidChange];
</span><ins>+
+    auto page = [self._webView _page];
+    auto* videoFullscreenManager = page ? page->videoFullscreenManager() : nullptr;
+    auto* videoFullscreenInterface = videoFullscreenManager ? videoFullscreenManager->controlsManagerInterface() : nullptr;
+    _videoFullscreenClient.setInterface(videoFullscreenInterface);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)placeholderWillMoveToSuperview:(UIView *)superview
</span><span class="lines">@@ -811,6 +919,53 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)willEnterPictureInPicture
+{
+    auto* interface = _videoFullscreenClient.interface();
+    if (!interface || !interface->pictureInPictureWasStartedWhenEnteringBackground())
+        return;
+
+    [_fullscreenViewController setAnimatingViewAlpha:0];
+}
+
+- (void)didEnterPictureInPicture
+{
+    _inPictureInPicture = YES;
+    [self requestExitFullScreen];
+}
+
+- (void)failedToEnterPictureInPicture
+{
+    auto* interface = _videoFullscreenClient.interface();
+    if (!interface || !interface->pictureInPictureWasStartedWhenEnteringBackground())
+        return;
+
+    [_fullscreenViewController setAnimatingViewAlpha:1];
+}
+
+- (void)prepareToExitPictureInPicture
+{
+    auto* interface = _videoFullscreenClient.interface();
+    if (!interface)
+        return;
+
+    interface->setReadyToStopPictureInPicture(NO);
+    interface->setWillEnterStandbyFromPictureInPicture(YES);
+    _returnToFullscreenFromPictureInPicture = YES;
+
+    if (!_exitingFullScreen)
+        [self requestEnterFullScreen];
+    else
+        _enterRequested = YES;
+}
+
+- (void)didExitPictureInPicture
+{
+    _inPictureInPicture = NO;
+    if (!_returnToFullscreenFromPictureInPicture && ![self isFullScreen])
+        _videoFullscreenClient.setInterface(nullptr);
+}
+
</ins><span class="cx"> #pragma mark -
</span><span class="cx"> #pragma mark UIGestureRecognizerDelegate
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessFullScreenWebFullScreenManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.cpp (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.cpp       2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.cpp  2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> #include <WebCore/RenderLayerBacking.h>
</span><span class="cx"> #include <WebCore/RenderView.h>
</span><span class="cx"> #include <WebCore/Settings.h>
</span><ins>+#include <WebCore/UserGestureIndicator.h>
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS_FAMILY) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
</span><span class="cx"> #include "PlaybackSessionManager.h"
</span><span class="lines">@@ -136,6 +137,12 @@
</span><span class="cx">     if (!element)
</span><span class="cx">         return;
</span><span class="cx">     m_element = element;
</span><ins>+
+#if PLATFORM(IOS_FAMILY) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
+    if (auto* currentPlaybackControlsElement = m_page->playbackSessionManager().currentPlaybackControlsElement())
+        currentPlaybackControlsElement->prepareForVideoFullscreenStandby();
+#endif
+
</ins><span class="cx">     m_initialFrame = screenRectOfContents(m_element.get());
</span><span class="cx">     m_page->injectedBundleFullScreenClient().enterFullScreenForElement(m_page.get(), element);
</span><span class="cx"> }
</span><span class="lines">@@ -217,6 +224,16 @@
</span><span class="cx">     m_element->document().fullscreenManager().setAnimatingFullscreen(animating);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebFullScreenManager::requestEnterFullScreen()
+{
+    ASSERT(m_element);
+    if (!m_element)
+        return;
+
+    WebCore::UserGestureIndicator gestureIndicator(WebCore::ProcessingUserGesture);
+    m_element->document().fullscreenManager().requestFullscreenForElement(m_element.get(), FullscreenManager::ExemptIFrameAllowFullscreenRequirement);
+}
+
</ins><span class="cx"> void WebFullScreenManager::requestExitFullScreen()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_element);
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessFullScreenWebFullScreenManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.h 2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.h    2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -77,6 +77,7 @@
</span><span class="cx">     void setPIPStandbyElement(WebCore::HTMLVideoElement*);
</span><span class="cx"> 
</span><span class="cx">     void setAnimatingFullScreen(bool);
</span><ins>+    void requestEnterFullScreen();
</ins><span class="cx">     void requestExitFullScreen();
</span><span class="cx">     void saveScrollPosition();
</span><span class="cx">     void restoreScrollPosition();
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessFullScreenWebFullScreenManagermessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.messages.in (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.messages.in       2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/WebProcess/FullScreen/WebFullScreenManager.messages.in  2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -22,6 +22,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(FULLSCREEN_API)
</span><span class="cx"> messages -> WebFullScreenManager LegacyReceiver {
</span><ins>+    RequestEnterFullScreen()
</ins><span class="cx">     RequestExitFullScreen()
</span><span class="cx">     WillEnterFullScreen()
</span><span class="cx">     DidEnterFullScreen()
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessWebCoreSupportWebChromeClientcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp        2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp   2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -940,6 +940,11 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIDEO_PRESENTATION_MODE)
</span><span class="cx"> 
</span><ins>+void WebChromeClient::prepareForVideoFullscreen()
+{
+    m_page.videoFullscreenManager();
+}
+
</ins><span class="cx"> bool WebChromeClient::supportsVideoFullscreen(HTMLMediaElementEnums::VideoFullscreenMode mode)
</span><span class="cx"> {
</span><span class="cx">     return m_page.videoFullscreenManager().supportsVideoFullscreen(mode);
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessWebCoreSupportWebChromeClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h  2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h     2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -264,6 +264,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(VIDEO_PRESENTATION_MODE)
</span><ins>+    void prepareForVideoFullscreen() final;
</ins><span class="cx">     bool supportsVideoFullscreen(WebCore::HTMLMediaElementEnums::VideoFullscreenMode) final;
</span><span class="cx">     bool supportsVideoFullscreenStandby() final;
</span><span class="cx">     void setMockVideoPresentationModeEnabled(bool) final;
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcesscocoaVideoFullscreenManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.h (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.h    2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.h       2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -154,7 +154,7 @@
</span><span class="cx">     void setVideoLayerFrameFenced(PlaybackSessionContextIdentifier, WebCore::FloatRect bounds, IPC::Attachment fencePort);
</span><span class="cx">     void setVideoLayerGravityEnum(PlaybackSessionContextIdentifier, unsigned gravity);
</span><span class="cx">     void fullscreenModeChanged(PlaybackSessionContextIdentifier, WebCore::HTMLMediaElementEnums::VideoFullscreenMode);
</span><del>-    void fullscreenMayReturnToInline(PlaybackSessionContextIdentifier, bool isPageVisible);
</del><ins>+    void fullscreenWillReturnToInline(PlaybackSessionContextIdentifier, bool isPageVisible);
</ins><span class="cx">     void requestRouteSharingPolicyAndContextUID(PlaybackSessionContextIdentifier, Messages::VideoFullscreenManager::RequestRouteSharingPolicyAndContextUIDAsyncReply&&);
</span><span class="cx"> 
</span><span class="cx">     WebPage* m_page;
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcesscocoaVideoFullscreenManagermessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.messages.in (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.messages.in  2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.messages.in     2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -34,7 +34,7 @@
</span><span class="cx">     SetVideoLayerFrameFenced(WebKit::PlaybackSessionContextIdentifier contextId, WebCore::FloatRect bounds, IPC::Attachment fencePort)
</span><span class="cx">     SetVideoLayerGravityEnum(WebKit::PlaybackSessionContextIdentifier contextId, unsigned gravity)
</span><span class="cx">     FullscreenModeChanged(WebKit::PlaybackSessionContextIdentifier contextId, WebCore::HTMLMediaElementEnums::VideoFullscreenMode videoFullscreenMode)
</span><del>-    FullscreenMayReturnToInline(WebKit::PlaybackSessionContextIdentifier contextId, bool isPageVisible)
</del><ins>+    FullscreenWillReturnToInline(WebKit::PlaybackSessionContextIdentifier contextId, bool isPageVisible)
</ins><span class="cx">     RequestRouteSharingPolicyAndContextUID(WebKit::PlaybackSessionContextIdentifier contextId) -> (enum:uint8_t WebCore::RouteSharingPolicy routeSharingPolicy, String routingContextUID) Async
</span><span class="cx"> }
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcesscocoaVideoFullscreenManagermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm (265561 => 265562)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm   2020-08-12 20:11:37 UTC (rev 265561)
+++ trunk/Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm      2020-08-12 20:55:35 UTC (rev 265562)
</span><span class="lines">@@ -524,7 +524,7 @@
</span><span class="cx">     ensureModel(contextId).setVideoLayerGravity((MediaPlayerEnums::VideoGravity)gravity);
</span><span class="cx"> }
</span><span class="cx">     
</span><del>-void VideoFullscreenManager::fullscreenMayReturnToInline(PlaybackSessionContextIdentifier contextId, bool isPageVisible)
</del><ins>+void VideoFullscreenManager::fullscreenWillReturnToInline(PlaybackSessionContextIdentifier contextId, bool isPageVisible)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_page)
</span><span class="cx">         return;
</span></span></pre>
</div>
</div>

</body>
</html>