Scrunching a video to PiP can result in broken animation and leave Safari in a bad state
https://bugs.webkit.org/show_bug.cgi?id=213175
Reviewed by Jer Noble.
Source/WebCore:
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::setVideoFullscreenStandby):
(WebCore::HTMLMediaElement::setVideoFullscreenStandby):
The "standby" state is relevant to a video element only when its presentation mode is VideoFullscreenModeNone.
* platform/ios/VideoFullscreenInterfaceAVKit.h:
* platform/ios/VideoFullscreenInterfaceAVKit.mm:
(VideoFullscreenInterfaceAVKit::exitFullscreen):
(VideoFullscreenInterfaceAVKit::cleanupFullscreen):
Add a flag m_enteringPictureInPicture. Function exitFullscreen() and cleanupFullscreen() will check
m_enteringPictureInPicture and they will abort the process to exit fullscreen/picture-in-picture if the flag
is true. However, VideoFullscreenManager will retry to exit fullscreen/picture-in-picture after it confirms that
the previous starting picture-in-picture process is completed.
(VideoFullscreenInterfaceAVKit::willStartPictureInPicture):
Set the flag m_enteringPictureInPicture.
(VideoFullscreenInterfaceAVKit::didStartPictureInPicture):
Call m_fullscreenChangeObserver->didEnterFullscreen() if the entering picture-in-picture process is
started by the UI process (e.g., swipe-up gesture).
Clear m_standby and m_enteringPictureInPicture after the video element enters picture-in-picture.
Source/WebKit:
* UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
(-[WKFullScreenWindowController _completedExitFullScreen]):
Update _exitRequested after exiting fullscreen to make sure the following
enter fullscreen request can be processed.
(-[WKFullScreenWindowController _dismissFullscreenViewController]):
Make sure _completedExitFullScreen function will always execute.
(-[WKFullScreenWindowController _interactivePinchDismissChanged:]):
Remove a function call which corrupts the state machine under stress test.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@263760 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 3785c61..e59ca1a 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,32 @@
+2020-06-30 Peng Liu <peng.liu6@apple.com>
+
+ Scrunching a video to PiP can result in broken animation and leave Safari in a bad state
+ https://bugs.webkit.org/show_bug.cgi?id=213175
+
+ Reviewed by Jer Noble.
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::setVideoFullscreenStandby):
+ (WebCore::HTMLMediaElement::setVideoFullscreenStandby):
+ The "standby" state is relevant to a video element only when its presentation mode is VideoFullscreenModeNone.
+
+ * platform/ios/VideoFullscreenInterfaceAVKit.h:
+ * platform/ios/VideoFullscreenInterfaceAVKit.mm:
+ (VideoFullscreenInterfaceAVKit::exitFullscreen):
+ (VideoFullscreenInterfaceAVKit::cleanupFullscreen):
+ Add a flag m_enteringPictureInPicture. Function exitFullscreen() and cleanupFullscreen() will check
+ m_enteringPictureInPicture and they will abort the process to exit fullscreen/picture-in-picture if the flag
+ is true. However, VideoFullscreenManager will retry to exit fullscreen/picture-in-picture after it confirms that
+ the previous starting picture-in-picture process is completed.
+
+ (VideoFullscreenInterfaceAVKit::willStartPictureInPicture):
+ Set the flag m_enteringPictureInPicture.
+
+ (VideoFullscreenInterfaceAVKit::didStartPictureInPicture):
+ Call m_fullscreenChangeObserver->didEnterFullscreen() if the entering picture-in-picture process is
+ started by the UI process (e.g., swipe-up gesture).
+ Clear m_standby and m_enteringPictureInPicture after the video element enters picture-in-picture.
+
2020-06-30 Alex Christensen <achristensen@webkit.org>
Remove WTF::MD5
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
index bbd21b0..e4c44a4 100644
--- a/Source/WebCore/html/HTMLMediaElement.cpp
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -6049,7 +6049,10 @@
m_player->videoFullscreenStandbyChanged();
#endif
- if (m_videoFullscreenStandby || m_videoFullscreenMode != VideoFullscreenModeNone)
+ if (m_videoFullscreenMode != VideoFullscreenModeNone)
+ return;
+
+ if (m_videoFullscreenStandby)
document().page()->chrome().client().enterVideoFullscreenForVideoElement(downcast<HTMLVideoElement>(*this), m_videoFullscreenMode, m_videoFullscreenStandby);
else
document().page()->chrome().client().exitVideoFullscreenForVideoElement(downcast<HTMLVideoElement>(*this));
diff --git a/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h b/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h
index 357d9ae..24d1358 100644
--- a/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h
+++ b/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.h
@@ -219,6 +219,7 @@
bool m_waitingForPreparedToExit { false };
bool m_shouldIgnoreAVKitCallbackAboutExitFullscreenReason { false };
+ bool m_enteringPictureInPicture { false };
};
}
diff --git a/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm b/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm
index 4909e94..5402437 100644
--- a/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm
+++ b/Source/WebCore/platform/ios/VideoFullscreenInterfaceAVKit.mm
@@ -921,6 +921,9 @@
if (m_watchdogTimer.isActive())
m_watchdogTimer.stop();
+ if (m_enteringPictureInPicture)
+ return;
+
m_targetMode = HTMLMediaElementEnums::VideoFullscreenModeNone;
setInlineRect(finalRect, true);
@@ -930,9 +933,11 @@
void VideoFullscreenInterfaceAVKit::cleanupFullscreen()
{
+ LOG(Fullscreen, "VideoFullscreenInterfaceAVKit::cleanupFullscreen(%p)", this);
m_shouldIgnoreAVKitCallbackAboutExitFullscreenReason = false;
- LOG(Fullscreen, "VideoFullscreenInterfaceAVKit::cleanupFullscreen(%p)", this);
+ if (m_enteringPictureInPicture)
+ return;
m_cleanupNeedsReturnVideoContentLayer = true;
if (m_hasVideoContentLayer && m_fullscreenChangeObserver) {
@@ -1055,6 +1060,8 @@
void VideoFullscreenInterfaceAVKit::willStartPictureInPicture()
{
LOG(Fullscreen, "VideoFullscreenInterfaceAVKit::willStartPictureInPicture(%p)", this);
+ m_enteringPictureInPicture = true;
+
if (m_standby && !m_currentMode.hasVideo()) {
[m_window setHidden:NO];
[[m_playerViewController view] setHidden:NO];
@@ -1088,6 +1095,13 @@
if (m_enterFullscreenNeedsEnterPictureInPicture)
doEnterFullscreen();
+ else {
+ if (m_fullscreenChangeObserver)
+ m_fullscreenChangeObserver->didEnterFullscreen();
+ }
+
+ m_enteringPictureInPicture = false;
+ m_standby = false;
}
void VideoFullscreenInterfaceAVKit::failedToStartPictureInPicture()
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index f32131d..863dc37 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,19 @@
+2020-06-30 Peng Liu <peng.liu6@apple.com>
+
+ Scrunching a video to PiP can result in broken animation and leave Safari in a bad state
+ https://bugs.webkit.org/show_bug.cgi?id=213175
+
+ Reviewed by Jer Noble.
+
+ * UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm:
+ (-[WKFullScreenWindowController _completedExitFullScreen]):
+ Update _exitRequested after exiting fullscreen to make sure the following
+ enter fullscreen request can be processed.
+ (-[WKFullScreenWindowController _dismissFullscreenViewController]):
+ Make sure _completedExitFullScreen function will always execute.
+ (-[WKFullScreenWindowController _interactivePinchDismissChanged:]):
+ Remove a function call which corrupts the state machine under stress test.
+
2020-06-30 Antoine Quint <graouts@webkit.org>
[iOS] Crash under WebKit::WebPage::getFocusedElementInformation()
diff --git a/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm b/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm
index 8357647..46bce6a 100644
--- a/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm
+++ b/Source/WebKit/UIProcess/ios/fullscreen/WKFullScreenWindowControllerIOS.mm
@@ -779,6 +779,7 @@
[_fullscreenViewController setPrefersStatusBarHidden:YES];
_fullscreenViewController = nil;
+ _exitRequested = NO;
}
- (void)close
@@ -993,6 +994,11 @@
- (void)_dismissFullscreenViewController
{
+ if (!_fullscreenViewController) {
+ [self _completedExitFullScreen];
+ return;
+ }
+
[_fullscreenViewController setAnimating:YES];
[_fullscreenViewController dismissViewControllerAnimated:YES completion:^{
if (![self._webView _page])
@@ -1036,11 +1042,6 @@
- (void)_interactivePinchDismissChanged:(id)sender
{
- if (!_inInteractiveDismiss && _interactivePinchDismissGestureRecognizer.get().state == UIGestureRecognizerStateBegan) {
- [self _startToDismissFullscreenChanged:sender];
- return;
- }
-
CGFloat scale = [_interactivePinchDismissGestureRecognizer scale];
CGFloat velocity = [_interactivePinchDismissGestureRecognizer velocity];
CGFloat progress = std::min(1., std::max(0., 1 - scale));