Title: [271970] trunk
Revision
271970
Author
[email protected]
Date
2021-01-27 12:24:59 -0800 (Wed, 27 Jan 2021)

Log Message

WKWebView closeAllMediaPresentations API does not have a completion handler
https://bugs.webkit.org/show_bug.cgi?id=220741
<rdar://problem/73045904>

Reviewed by Youenn Fablet.

Source/WebKit:

Adds a completion handler to WKWebView closeAllMediaPresentations.
This required handling the case for video fullscreen, picture-in-picture,
and element fullscreen. Closing fullscreen requires multiple async
operations, some of which go out of WebKit scope like PIPViewControllerDelegate
functions, so for simplicity, the callbacks are stored in
the respective *FullscreenManagerProxy object and called when
didExitFullscreen() is executed. Any additional calls to closeAllMediaPresentations
made before the previous has finished will have their callbacks
appended to a vector and called when all presentations have closed.

* UIProcess/API/Cocoa/WKWebView.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView closeAllMediaPresentations:]):
(-[WKWebView _closeAllMediaPresentations]):
(-[WKWebView _allMediaPresentationsClosed]):
New SPI for testing. Previously these tests used _javascript_ to check
for inline video but updating the JS value is async and may not be completed
by the time didExitFullscreen() is called. So, this SPI will help avoid
flakiness.

* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/Cocoa/VideoFullscreenManagerProxy.h:
* UIProcess/Cocoa/VideoFullscreenManagerProxy.mm:
(WebKit::VideoFullscreenModelContext::requestFullscreenModeWithCallback):
(WebKit::VideoFullscreenManagerProxy::~VideoFullscreenManagerProxy):
(WebKit::VideoFullscreenManagerProxy::forEachSession):
(WebKit::VideoFullscreenManagerProxy::callCloseCompletionHandlers):
(WebKit::VideoFullscreenManagerProxy::requestFullscreenModeWithCallback):
(WebKit::VideoFullscreenManagerProxy::didExitFullscreen):
Add a new requestFullscreenModeWithCallback function
for VideoFullscreenModelContext which is used when closing fullscreen
video. This way we don't need to adjust an overridden function.

* UIProcess/WebFullScreenManagerProxy.cpp:
(WebKit::WebFullScreenManagerProxy::~WebFullScreenManagerProxy):
(WebKit::WebFullScreenManagerProxy::callCloseCompletionHandlers):
(WebKit::WebFullScreenManagerProxy::closeWithCallback):
(WebKit::WebFullScreenManagerProxy::didExitFullScreen):
* UIProcess/WebFullScreenManagerProxy.h:
Ditto, create a new function here to be used only for closing
media presentations so we don't have to pass empty completion handlers
unnecessarily.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::pauseAllMediaPlayback):
(WebKit::WebPageProxy::suspendAllMediaPlayback):
(WebKit::WebPageProxy::resumeAllMediaPlayback):
* UIProcess/WebPageProxy.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::pauseAllMediaPlayback):
(WebKit::WebPage::suspendAllMediaPlayback):
(WebKit::WebPage::resumeAllMediaPlayback):
* WebProcess/WebPage/WebPage.h:
Remove unnecessary voids.

Tools:

Update API tests to use the new completion handler. Move from using JS
to a new SPI to check for inline video to avoid flakiness because the
JS value is async and may not be completed by the time
didExitFullscreen() is called.

Add a new case for multiple sequential calls to
closeAllMediaPresentations.

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

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (271969 => 271970)


--- trunk/Source/WebKit/ChangeLog	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/ChangeLog	2021-01-27 20:24:59 UTC (rev 271970)
@@ -1,3 +1,66 @@
+2021-01-27  Kate Cheney  <[email protected]>
+
+        WKWebView closeAllMediaPresentations API does not have a completion handler
+        https://bugs.webkit.org/show_bug.cgi?id=220741
+        <rdar://problem/73045904>
+
+        Reviewed by Youenn Fablet.
+
+        Adds a completion handler to WKWebView closeAllMediaPresentations.
+        This required handling the case for video fullscreen, picture-in-picture,
+        and element fullscreen. Closing fullscreen requires multiple async
+        operations, some of which go out of WebKit scope like PIPViewControllerDelegate
+        functions, so for simplicity, the callbacks are stored in
+        the respective *FullscreenManagerProxy object and called when
+        didExitFullscreen() is executed. Any additional calls to closeAllMediaPresentations
+        made before the previous has finished will have their callbacks
+        appended to a vector and called when all presentations have closed.
+
+        * UIProcess/API/Cocoa/WKWebView.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView closeAllMediaPresentations:]):
+        (-[WKWebView _closeAllMediaPresentations]):
+        (-[WKWebView _allMediaPresentationsClosed]):
+        New SPI for testing. Previously these tests used _javascript_ to check
+        for inline video but updating the JS value is async and may not be completed
+        by the time didExitFullscreen() is called. So, this SPI will help avoid
+        flakiness.
+
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/Cocoa/VideoFullscreenManagerProxy.h:
+        * UIProcess/Cocoa/VideoFullscreenManagerProxy.mm:
+        (WebKit::VideoFullscreenModelContext::requestFullscreenModeWithCallback):
+        (WebKit::VideoFullscreenManagerProxy::~VideoFullscreenManagerProxy):
+        (WebKit::VideoFullscreenManagerProxy::forEachSession):
+        (WebKit::VideoFullscreenManagerProxy::callCloseCompletionHandlers):
+        (WebKit::VideoFullscreenManagerProxy::requestFullscreenModeWithCallback):
+        (WebKit::VideoFullscreenManagerProxy::didExitFullscreen):
+        Add a new requestFullscreenModeWithCallback function
+        for VideoFullscreenModelContext which is used when closing fullscreen
+        video. This way we don't need to adjust an overridden function.
+
+        * UIProcess/WebFullScreenManagerProxy.cpp:
+        (WebKit::WebFullScreenManagerProxy::~WebFullScreenManagerProxy):
+        (WebKit::WebFullScreenManagerProxy::callCloseCompletionHandlers):
+        (WebKit::WebFullScreenManagerProxy::closeWithCallback):
+        (WebKit::WebFullScreenManagerProxy::didExitFullScreen):
+        * UIProcess/WebFullScreenManagerProxy.h:
+        Ditto, create a new function here to be used only for closing
+        media presentations so we don't have to pass empty completion handlers
+        unnecessarily.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::pauseAllMediaPlayback):
+        (WebKit::WebPageProxy::suspendAllMediaPlayback):
+        (WebKit::WebPageProxy::resumeAllMediaPlayback):
+        * UIProcess/WebPageProxy.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::pauseAllMediaPlayback):
+        (WebKit::WebPage::suspendAllMediaPlayback):
+        (WebKit::WebPage::resumeAllMediaPlayback):
+        * WebProcess/WebPage/WebPage.h:
+        Remove unnecessary voids.
+
 2021-01-27  Devin Rousso  <[email protected]>
 
         [iOS] expose existing macOS-only `-[WKWebView _pageExtendedBackgroundColor]` SPI

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.h (271969 => 271970)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.h	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.h	2021-01-27 20:24:59 UTC (rev 271970)
@@ -327,7 +327,7 @@
 /*! @abstract Closes all out-of-window media presentations in a WKWebView.
  @discussion Includes picture-in-picture and fullscreen.
  */
-- (void)closeAllMediaPresentations WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (void)closeAllMediaPresentations:(void (^_Nullable)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 /*! @abstract Pauses media playback in WKWebView.
  @discussion Pauses media playback. Media in the page can be restarted by calling play() on a media element or resume() on an AudioContext.

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (271969 => 271970)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2021-01-27 20:24:59 UTC (rev 271970)
@@ -137,6 +137,7 @@
 #import <WebCore/WebViewVisualIdentificationOverlay.h>
 #import <WebCore/WritingMode.h>
 #import <wtf/BlockPtr.h>
+#import <wtf/CallbackAggregator.h>
 #import <wtf/HashMap.h>
 #import <wtf/MathExtras.h>
 #import <wtf/NeverDestroyed.h>
@@ -907,17 +908,19 @@
     return false;
 }
 
-- (void)closeAllMediaPresentations
+- (void)closeAllMediaPresentations:(void (^)(void))completionHandler
 {
+    auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
+
 #if ENABLE(FULLSCREEN_API)
     if (auto videoFullscreenManager = _page->videoFullscreenManager()) {
-        videoFullscreenManager->forEachSession([] (auto& model, auto& interface) {
-            model.requestFullscreenMode(WebCore::HTMLMediaElementEnums::VideoFullscreenModeNone);
+        videoFullscreenManager->forEachSession([callbackAggregator] (auto& model, auto& interface) mutable {
+            model.requestFullscreenModeWithCallback(WebCore::HTMLMediaElementEnums::VideoFullscreenModeNone, false, [callbackAggregator] { });
         });
     }
 
     if (auto fullScreenManager = _page->fullScreenManager(); fullScreenManager && fullScreenManager->isFullScreen())
-        fullScreenManager->close();
+        fullScreenManager->closeWithCallback([callbackAggregator] { });
 #endif
 }
 
@@ -1991,7 +1994,7 @@
 
 - (void)_closeAllMediaPresentations
 {
-    [self closeAllMediaPresentations];
+    [self closeAllMediaPresentations:nil];
 }
 
 - (void)_stopMediaCapture
@@ -2354,6 +2357,25 @@
     [self _evaluateJavaScript:functionBody asAsyncFunction:YES withSourceURL:nil withArguments:arguments forceUserGesture:YES inFrame:frame inWorld:contentWorld completionHandler:completionHandler];
 }
 
+
+- (BOOL)_allMediaPresentationsClosed
+{
+#if ENABLE(FULLSCREEN_API)
+    bool hasOpenMediaPresentations = false;
+    if (auto videoFullscreenManager = _page->videoFullscreenManager()) {
+        hasOpenMediaPresentations = videoFullscreenManager->hasMode(WebCore::HTMLMediaElementEnums::VideoFullscreenModePictureInPicture)
+            || videoFullscreenManager->hasMode(WebCore::HTMLMediaElementEnums::VideoFullscreenModeStandard);
+    }
+
+    if (!hasOpenMediaPresentations && _page->fullScreenManager() && _page->fullScreenManager()->isFullScreen())
+        hasOpenMediaPresentations = true;
+
+    return !hasOpenMediaPresentations;
+#else
+    return true;
+#endif
+}
+
 - (void)_evaluateJavaScript:(NSString *)_javascript_String inFrame:(WKFrameInfo *)frame inContentWorld:(WKContentWorld *)contentWorld completionHandler:(void (^)(id, NSError *error))completionHandler
 {
     [self _evaluateJavaScript:_javascript_String asAsyncFunction:NO withSourceURL:nil withArguments:nil forceUserGesture:YES inFrame:frame inWorld:contentWorld completionHandler:completionHandler];

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (271969 => 271970)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h	2021-01-27 20:24:59 UTC (rev 271970)
@@ -222,6 +222,8 @@
 - (void)_evaluateJavaScript:(NSString *)_javascript_String withSourceURL:(NSURL *)sourceURL inFrame:(WKFrameInfo *)frame inContentWorld:(WKContentWorld *)contentWorld completionHandler:(void (^)(id, NSError * error))completionHandler WK_API_AVAILABLE(macos(11.0), ios(14.0));
 - (void)_callAsyncJavaScript:(NSString *)functionBody arguments:(NSDictionary<NSString *, id> *)arguments inFrame:(WKFrameInfo *)frame inContentWorld:(WKContentWorld *)contentWorld completionHandler:(void (^)(id, NSError *error))completionHandler WK_API_AVAILABLE(macos(11.0), ios(14.0));
 
+- (BOOL)_allMediaPresentationsClosed WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+
 @property (nonatomic, setter=_setLayoutMode:) _WKLayoutMode _layoutMode;
 // For use with _layoutMode = _WKLayoutModeFixedSize:
 @property (nonatomic, setter=_setFixedLayoutSize:) CGSize _fixedLayoutSize;

Modified: trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h (271969 => 271970)


--- trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.h	2021-01-27 20:24:59 UTC (rev 271970)
@@ -78,6 +78,7 @@
 
     PlatformView *layerHostView() const { return m_layerHostView.get(); }
     void setLayerHostView(RetainPtr<PlatformView>&& layerHostView) { m_layerHostView = WTFMove(layerHostView); }
+    void requestFullscreenModeWithCallback(WebCore::HTMLMediaElementEnums::VideoFullscreenMode, bool finishedWithMedia, CompletionHandler<void()>&&);
 
 private:
     VideoFullscreenModelContext(VideoFullscreenManagerProxy&, PlaybackSessionModelContext&, PlaybackSessionContextIdentifier);
@@ -152,7 +153,7 @@
     void setClient(VideoFullscreenManagerProxyClient* client) { m_client = makeWeakPtr(client); }
     VideoFullscreenManagerProxyClient* client() const { return m_client.get(); }
 
-    void forEachSession(Function<void(WebCore::VideoFullscreenModel&, PlatformVideoFullscreenInterface&)>&&);
+    void forEachSession(Function<void(VideoFullscreenModelContext&, PlatformVideoFullscreenInterface&)>&&);
 
 private:
     friend class VideoFullscreenModelContext;
@@ -200,6 +201,9 @@
     void fullscreenModeChanged(PlaybackSessionContextIdentifier, WebCore::HTMLMediaElementEnums::VideoFullscreenMode);
     void fullscreenMayReturnToInline(PlaybackSessionContextIdentifier);
 
+    void requestFullscreenModeWithCallback(PlaybackSessionContextIdentifier, WebCore::HTMLMediaElementEnums::VideoFullscreenMode, bool finishedWithMedia, CompletionHandler<void()>&&);
+    void callCloseCompletionHandlers();
+
     bool m_mockVideoPresentationModeEnabled { false };
     WebCore::FloatSize m_mockPictureInPictureWindowSize { DefaultMockPictureInPictureWindowWidth, DefaultMockPictureInPictureWindowHeight };
 
@@ -209,6 +213,7 @@
     PlaybackSessionContextIdentifier m_controlsManagerContextId;
     HashMap<PlaybackSessionContextIdentifier, int> m_clientCounts;
     WeakPtr<VideoFullscreenManagerProxyClient> m_client;
+    Vector<CompletionHandler<void()>> m_closeCompletionHandlers;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm (271969 => 271970)


--- trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/UIProcess/Cocoa/VideoFullscreenManagerProxy.mm	2021-01-27 20:24:59 UTC (rev 271970)
@@ -181,6 +181,16 @@
     m_clients.remove(&client);
 }
 
+void VideoFullscreenModelContext::requestFullscreenModeWithCallback(HTMLMediaElementEnums::VideoFullscreenMode mode, bool finishedWithMedia, CompletionHandler<void()>&& completionHandler)
+{
+    if (!m_manager) {
+        completionHandler();
+        return;
+    }
+
+    m_manager->requestFullscreenModeWithCallback(m_contextId, mode, finishedWithMedia, WTFMove(completionHandler));
+}
+
 void VideoFullscreenModelContext::requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenMode mode, bool finishedWithMedia)
 {
     if (m_manager)
@@ -328,6 +338,8 @@
 
 VideoFullscreenManagerProxy::~VideoFullscreenManagerProxy()
 {
+    callCloseCompletionHandlers();
+
     if (!m_page)
         return;
     invalidate();
@@ -475,7 +487,7 @@
     m_clientCounts.set(contextId, clientCount);
 }
 
-void VideoFullscreenManagerProxy::forEachSession(Function<void(VideoFullscreenModel&, PlatformVideoFullscreenInterface&)>&& callback)
+void VideoFullscreenManagerProxy::forEachSession(Function<void(VideoFullscreenModelContext&, PlatformVideoFullscreenInterface&)>&& callback)
 {
     if (m_contextMap.isEmpty())
         return;
@@ -727,6 +739,23 @@
 
 #pragma mark Messages to VideoFullscreenManager
 
+void VideoFullscreenManagerProxy::callCloseCompletionHandlers()
+{
+    auto closeMediaCallbacks = WTFMove(m_closeCompletionHandlers);
+    for (auto& callback : closeMediaCallbacks)
+        callback();
+}
+
+void VideoFullscreenManagerProxy::requestFullscreenModeWithCallback(PlaybackSessionContextIdentifier contextId, WebCore::HTMLMediaElementEnums::VideoFullscreenMode mode, bool finishedWithMedia, CompletionHandler<void()>&& completionHandler)
+{
+    if (mode == WebCore::HTMLMediaElementEnums::VideoFullscreenModeNone
+        && (hasMode(WebCore::HTMLMediaElementEnums::VideoFullscreenModePictureInPicture)
+            || hasMode(WebCore::HTMLMediaElementEnums::VideoFullscreenModeStandard)))
+        m_closeCompletionHandlers.append(WTFMove(completionHandler));
+
+    requestFullscreenMode(contextId, mode, finishedWithMedia);
+}
+
 void VideoFullscreenManagerProxy::requestFullscreenMode(PlaybackSessionContextIdentifier contextId, WebCore::HTMLMediaElementEnums::VideoFullscreenMode mode, bool finishedWithMedia)
 {
     m_page->send(Messages::VideoFullscreenManager::RequestFullscreenMode(contextId, mode, finishedWithMedia));
@@ -766,10 +795,13 @@
     m_page->send(Messages::VideoFullscreenManager::DidExitFullscreen(contextId));
 
 #if PLATFORM(IOS_FAMILY)
-    if (ensureInterface(contextId).changingStandbyOnly())
+    if (ensureInterface(contextId).changingStandbyOnly()) {
+        callCloseCompletionHandlers();
         return;
+    }
 #endif
     m_page->didExitFullscreen();
+    callCloseCompletionHandlers();
 }
 
 void VideoFullscreenManagerProxy::didEnterFullscreen(PlaybackSessionContextIdentifier contextId, const WebCore::FloatSize& size)

Modified: trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.cpp (271969 => 271970)


--- trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.cpp	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.cpp	2021-01-27 20:24:59 UTC (rev 271970)
@@ -51,6 +51,7 @@
 {
     m_page.process().removeMessageReceiver(Messages::WebFullScreenManagerProxy::messageReceiverName(), m_page.webPageID());
     m_client.closeFullScreenManager();
+    callCloseCompletionHandlers();
 }
 
 void WebFullScreenManagerProxy::willEnterFullScreen()
@@ -76,6 +77,19 @@
     m_page.send(Messages::WebFullScreenManager::WillExitFullScreen());
 }
 
+void WebFullScreenManagerProxy::callCloseCompletionHandlers()
+{
+    auto closeMediaCallbacks = WTFMove(m_closeCompletionHandlers);
+    for (auto& callback : closeMediaCallbacks)
+        callback();
+}
+
+void WebFullScreenManagerProxy::closeWithCallback(CompletionHandler<void()>&& completionHandler)
+{
+    m_closeCompletionHandlers.append(WTFMove(completionHandler));
+    close();
+}
+
 void WebFullScreenManagerProxy::didExitFullScreen()
 {
     m_page.fullscreenClient().didExitFullscreen(&m_page);
@@ -85,6 +99,7 @@
         if (WebAutomationSession* automationSession = m_page.process().processPool().automationSession())
             automationSession->didExitFullScreenForPage(m_page);
     }
+    callCloseCompletionHandlers();
 }
 
 void WebFullScreenManagerProxy::setAnimatingFullScreen(bool animating)

Modified: trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.h (271969 => 271970)


--- trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.h	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/UIProcess/WebFullScreenManagerProxy.h	2021-01-27 20:24:59 UTC (rev 271970)
@@ -28,9 +28,11 @@
 #if ENABLE(FULLSCREEN_API)
 
 #include "MessageReceiver.h"
+#include <wtf/CompletionHandler.h>
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Seconds.h>
+#include <wtf/Vector.h>
 
 namespace WebCore {
 class IntRect;
@@ -77,6 +79,7 @@
     void setFullscreenInsets(const WebCore::FloatBoxExtent&);
     void setFullscreenAutoHideDuration(Seconds);
     void setFullscreenControlsHidden(bool);
+    void closeWithCallback(CompletionHandler<void()>&&);
 
 private:
     void supportsFullScreen(bool withKeyboard, CompletionHandler<void(bool)>&&);
@@ -84,6 +87,7 @@
     void exitFullScreen();
     void beganEnterFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame);
     void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame);
+    void callCloseCompletionHandlers();
 
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
     void didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, std::unique_ptr<IPC::Encoder>&) override;
@@ -91,6 +95,7 @@
     WebPageProxy& m_page;
     WebFullScreenManagerProxyClient& m_client;
     bool m_blocksReturnToFullscreenFromPictureInPicture { false };
+    Vector<CompletionHandler<void()>> m_closeCompletionHandlers;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (271969 => 271970)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-01-27 20:24:59 UTC (rev 271970)
@@ -5992,7 +5992,7 @@
     sendWithAsyncReply(Messages::WebPage::RequestMediaPlaybackState(), WTFMove(completionHandler));
 }
 
-void WebPageProxy::pauseAllMediaPlayback(CompletionHandler<void(void)>&& completionHandler)
+void WebPageProxy::pauseAllMediaPlayback(CompletionHandler<void()>&& completionHandler)
 {
     if (!hasRunningProcess()) {
         completionHandler();
@@ -6002,7 +6002,7 @@
     sendWithAsyncReply(Messages::WebPage::PauseAllMediaPlayback(), WTFMove(completionHandler));
 }
 
-void WebPageProxy::suspendAllMediaPlayback(CompletionHandler<void(void)>&& completionHandler)
+void WebPageProxy::suspendAllMediaPlayback(CompletionHandler<void()>&& completionHandler)
 {
     m_suspendMediaPlaybackCounter++;
     if (m_mediaPlaybackIsSuspended) {
@@ -6019,7 +6019,7 @@
     sendWithAsyncReply(Messages::WebPage::SuspendAllMediaPlayback(), WTFMove(completionHandler));
 }
 
-void WebPageProxy::resumeAllMediaPlayback(CompletionHandler<void(void)>&& completionHandler)
+void WebPageProxy::resumeAllMediaPlayback(CompletionHandler<void()>&& completionHandler)
 {
     if (m_suspendMediaPlaybackCounter > 0)
         m_suspendMediaPlaybackCounter--;

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (271969 => 271970)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-01-27 20:24:59 UTC (rev 271970)
@@ -1335,9 +1335,9 @@
     bool mediaCaptureEnabled() const { return m_mediaCaptureEnabled; }
     void stopMediaCapture();
 
-    void pauseAllMediaPlayback(CompletionHandler<void(void)>&&);
-    void suspendAllMediaPlayback(CompletionHandler<void(void)>&&);
-    void resumeAllMediaPlayback(CompletionHandler<void(void)>&&);
+    void pauseAllMediaPlayback(CompletionHandler<void()>&&);
+    void suspendAllMediaPlayback(CompletionHandler<void()>&&);
+    void resumeAllMediaPlayback(CompletionHandler<void()>&&);
     void requestMediaPlaybackState(CompletionHandler<void(WebKit::MediaPlaybackState)>&&);
 
 #if ENABLE(POINTER_LOCK)

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (271969 => 271970)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-01-27 20:24:59 UTC (rev 271970)
@@ -845,19 +845,19 @@
     completionHandler(MediaPlaybackState::MediaPlaybackPlaying);
 }
 
-void WebPage::pauseAllMediaPlayback(CompletionHandler<void(void)>&& completionHandler)
+void WebPage::pauseAllMediaPlayback(CompletionHandler<void()>&& completionHandler)
 {
     m_page->pauseAllMediaPlayback();
     completionHandler();
 }
 
-void WebPage::suspendAllMediaPlayback(CompletionHandler<void(void)>&& completionHandler)
+void WebPage::suspendAllMediaPlayback(CompletionHandler<void()>&& completionHandler)
 {
     m_page->suspendAllMediaPlayback();
     completionHandler();
 }
 
-void WebPage::resumeAllMediaPlayback(CompletionHandler<void(void)>&& completionHandler)
+void WebPage::resumeAllMediaPlayback(CompletionHandler<void()>&& completionHandler)
 {
     m_page->resumeAllMediaPlayback();
     completionHandler();

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (271969 => 271970)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2021-01-27 20:24:59 UTC (rev 271970)
@@ -1671,9 +1671,9 @@
 
     void requestMediaPlaybackState(CompletionHandler<void(WebKit::MediaPlaybackState)>&&);
 
-    void pauseAllMediaPlayback(CompletionHandler<void(void)>&&);
-    void suspendAllMediaPlayback(CompletionHandler<void(void)>&&);
-    void resumeAllMediaPlayback(CompletionHandler<void(void)>&&);
+    void pauseAllMediaPlayback(CompletionHandler<void()>&&);
+    void suspendAllMediaPlayback(CompletionHandler<void()>&&);
+    void resumeAllMediaPlayback(CompletionHandler<void()>&&);
 
     void advanceToNextMisspelling(bool startBeforeSelection);
     void changeSpellingToWord(const String& word);

Modified: trunk/Tools/ChangeLog (271969 => 271970)


--- trunk/Tools/ChangeLog	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Tools/ChangeLog	2021-01-27 20:24:59 UTC (rev 271970)
@@ -1,3 +1,22 @@
+2021-01-27  Kate Cheney  <[email protected]>
+
+        WKWebView closeAllMediaPresentations API does not have a completion handler
+        https://bugs.webkit.org/show_bug.cgi?id=220741
+        <rdar://problem/73045904>
+
+        Reviewed by Youenn Fablet.
+
+        Update API tests to use the new completion handler. Move from using JS
+        to a new SPI to check for inline video to avoid flakiness because the
+        JS value is async and may not be completed by the time
+        didExitFullscreen() is called.
+
+        Add a new case for multiple sequential calls to
+        closeAllMediaPresentations.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKWebViewCloseAllMediaPresentations.mm:
+        (TEST):
+
 2021-01-27  Devin Rousso  <[email protected]>
 
         [iOS] expose existing macOS-only `-[WKWebView _pageExtendedBackgroundColor]` SPI

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewCloseAllMediaPresentations.mm (271969 => 271970)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewCloseAllMediaPresentations.mm	2021-01-27 20:10:32 UTC (rev 271969)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebViewCloseAllMediaPresentations.mm	2021-01-27 20:24:59 UTC (rev 271970)
@@ -36,21 +36,8 @@
 // We can enable the test for old iOS versions after <rdar://problem/63572534> is fixed.
 #if ENABLE(VIDEO_PRESENTATION_MODE) && (PLATFORM(MAC) || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 140000))
 
-TEST(WKWebViewCloseAllMediaPresentations, PictureInPicture)
+static void loadPictureInPicture(RetainPtr<TestWKWebView> webView)
 {
-    if (!WebCore::supportsPictureInPicture())
-        return;
-
-    [[NSUserDefaults standardUserDefaults] registerDefaults:@{
-        @"WebCoreLogging": @"Fullscreen=debug",
-        @"WebKit2Logging": @"Fullscreen=debug",
-    }];
-
-
-    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
-    [[configuration preferences] _setAllowsPictureInPictureMediaPlayback:YES];
-    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration addToWindow:YES]);
-
     [webView synchronouslyLoadHTMLString:@"<video src="" webkit-playsinline playsinline loop></video>"];
 
     [[NSUserDefaults standardUserDefaults] registerDefaults:@{
@@ -71,15 +58,32 @@
 
         TestWebKitAPI::Util::sleep(0.5);
     } while (true);
+}
 
-    presentationModeChanged = false;
-    [webView performAfterReceivingMessage:@"presentationmodechanged" action:^{ presentationModeChanged = true; }];
+TEST(WKWebViewCloseAllMediaPresentations, PictureInPicture)
+{
+    if (!WebCore::supportsPictureInPicture())
+        return;
 
-    [webView _closeAllMediaPresentations];
+    [[NSUserDefaults standardUserDefaults] registerDefaults:@{
+        @"WebCoreLogging": @"Fullscreen=debug",
+        @"WebKit2Logging": @"Fullscreen=debug",
+    }];
 
-    ASSERT(TestWebKitAPI::Util::runFor(&presentationModeChanged, 10));
 
-    EXPECT_STREQ([webView stringByEvaluatingJavaScript:@"document.querySelector('video').webkitPresentationMode"].UTF8String, "inline");
+    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+    [[configuration preferences] _setAllowsPictureInPictureMediaPlayback:YES];
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration addToWindow:YES]);
+
+    loadPictureInPicture(webView);
+
+    static bool isDone = false;
+    [webView closeAllMediaPresentations:^{
+        isDone = true;
+    }];
+    TestWebKitAPI::Util::run(&isDone);
+
+    EXPECT_TRUE([webView _allMediaPresentationsClosed]);
 }
 
 #endif
@@ -109,14 +113,13 @@
         TestWebKitAPI::Util::sleep(0.5);
     } while (true);
 
-    presentationModeChanged = false;
-    [webView performAfterReceivingMessage:@"presentationmodechanged" action:^{ presentationModeChanged = true; }];
-
-    [webView _closeAllMediaPresentations];
-
-    TestWebKitAPI::Util::run(&presentationModeChanged);
-
-    EXPECT_STREQ([webView stringByEvaluatingJavaScript:@"document.querySelector('video').webkitPresentationMode"].UTF8String, "inline");
+    static bool isDone = false;
+    [webView closeAllMediaPresentations:^{
+        isDone = true;
+    }];
+    TestWebKitAPI::Util::run(&isDone);
+    
+    EXPECT_TRUE([webView _allMediaPresentationsClosed]);
 }
 
 TEST(WKWebViewCloseAllMediaPresentations, ElementFullscreen)
@@ -138,11 +141,45 @@
     fullscreenModeChanged = false;
     [webView performAfterReceivingMessage:@"fullscreenchange" action:^{ fullscreenModeChanged = true; }];
 
-    [webView _closeAllMediaPresentations];
+    static bool isDone = false;
+    [webView closeAllMediaPresentations:^{
+        isDone = true;
+    }];
+    TestWebKitAPI::Util::run(&isDone);
+    
+    EXPECT_TRUE([webView _allMediaPresentationsClosed]);
+}
 
-    TestWebKitAPI::Util::run(&fullscreenModeChanged);
+TEST(WKWebViewCloseAllMediaPresentations, MultipleSequentialCloseAllMediaPresentations)
+{
+    if (!WebCore::supportsPictureInPicture())
+        return;
 
-    EXPECT_STREQ([webView stringByEvaluatingJavaScript:@"document.webkitFullscreenElement"].UTF8String, "<null>");
+    [[NSUserDefaults standardUserDefaults] registerDefaults:@{
+        @"WebCoreLogging": @"Fullscreen=debug",
+        @"WebKit2Logging": @"Fullscreen=debug",
+    }];
+
+    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+    [[configuration preferences] _setAllowsPictureInPictureMediaPlayback:YES];
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration addToWindow:YES]);
+
+    loadPictureInPicture(webView);
+
+    static bool firstIsDone = false;
+    [webView closeAllMediaPresentations:^{
+        firstIsDone = true;
+    }];
+
+    static bool secondIsDone = false;
+    [webView closeAllMediaPresentations:^{
+        secondIsDone = true;
+    }];
+
+    TestWebKitAPI::Util::run(&firstIsDone);
+    TestWebKitAPI::Util::run(&secondIsDone);
+
+    EXPECT_TRUE([webView _allMediaPresentationsClosed]);
 }
 
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to