Title: [267709] trunk
Revision
267709
Author
[email protected]
Date
2020-09-28 11:23:58 -0700 (Mon, 28 Sep 2020)

Log Message

[iOS] unable to airplay directly loaded fullscreen video
https://bugs.webkit.org/show_bug.cgi?id=216858
<rdar://problem/68746321>

Reviewed by Eric Carlson.

Source/WebCore:

It's possible that `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` is queried before a
"real" `MediaPlayerPrivate` (i.e. not `NullMediaPlayerPrivate`) is initialized through one
of the registered `MediaPlayerFactory` "engine"s. It's further possible that the value
returned by `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` will change as the new
"real" `MediaPlayerPrivate` may have different logic. In this case, the `MediaPlayer`
doesn't update its client (and therefore nothing "up" the tree, including the client's
clients) with the new `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` value, meaning
that the old value will still be used.

Add piping such that when the `MediaPlayerFactory` "engine" changes, the `MediaPlayer`
notifies its client (which is further piped "up" the tree to the client's clients) which
eventually causes `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` to be re-evaluated.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::mediaEngineWasUpdated):
* page/Page.h:
* page/Page.cpp:
(WebCore::Page::playbackControlsMediaEngineChanged): Added.
* page/ChromeClient.h:
(WebCore::ChromeClient::playbackControlsMediaEngineChanged): Added.

* platform/cocoa/PlaybackSessionModelMediaElement.h:
* platform/cocoa/PlaybackSessionModelMediaElement.mm:
(WebCore::PlaybackSessionModelMediaElement::mediaEngineChanged): Added.

Source/WebKit:

It's possible that `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` is queried before a
"real" `MediaPlayerPrivate` (i.e. not `NullMediaPlayerPrivate`) is initialized through one
of the registered `MediaPlayerFactory` "engine"s. It's further possible that the value
returned by `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` will change as the new
"real" `MediaPlayerPrivate` may have different logic. In this case, the `MediaPlayer`
doesn't update its client (and therefore nothing "up" the tree, including the client's
clients) with the new `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` value, meaning
that the old value will still be used.

Add piping such that when the `MediaPlayerFactory` "engine" changes, the `MediaPlayer`
notifies its client (which is further piped "up" the tree to the client's clients) which
eventually causes `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` to be re-evaluated.

* WebProcess/WebCoreSupport/WebChromeClient.h:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::playbackControlsMediaEngineChanged): Added.
* WebProcess/cocoa/PlaybackSessionManager.h:
* WebProcess/cocoa/PlaybackSessionManager.mm:
(WebKit::PlaybackSessionManager::mediaEngineChanged): Added.

* UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
* UIProcess/API/Cocoa/WKWebViewTesting.mm:
(-[WKWebView _wirelessVideoPlaybackDisabled]): Added.
* UIProcess/Cocoa/PlaybackSessionManagerProxy.h:
* UIProcess/Cocoa/PlaybackSessionManagerProxy.mm:
(WebKit::PlaybackSessionManagerProxy::wirelessVideoPlaybackDisabled): Added.
Create additional functions for piping data to tests.

Source/WebKitLegacy/mac:

It's possible that `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` is queried before a
"real" `MediaPlayerPrivate` (i.e. not `NullMediaPlayerPrivate`) is initialized through one
of the registered `MediaPlayerFactory` "engine"s. It's further possible that the value
returned by `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` will change as the new
"real" `MediaPlayerPrivate` may have different logic. In this case, the `MediaPlayer`
doesn't update its client (and therefore nothing "up" the tree, including the client's
clients) with the new `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` value, meaning
that the old value will still be used.

Add piping such that when the `MediaPlayerFactory` "engine" changes, the `MediaPlayer`
notifies its client (which is further piped "up" the tree to the client's clients) which
eventually causes `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` to be re-evaluated.

* WebCoreSupport/WebChromeClient.h:
* WebCoreSupport/WebChromeClient.mm:
(WebChromeClient::playbackControlsMediaEngineChanged): Added.
* WebView/WebViewInternal.h:
* WebView/WebView.mm:
(-[WebView _playbackControlsMediaEngineChanged]): Added.

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/MediaDocument.mm: Added.
(MediaDocument.WirelessPlaybackEnabled):

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (267708 => 267709)


--- trunk/Source/WebCore/ChangeLog	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebCore/ChangeLog	2020-09-28 18:23:58 UTC (rev 267709)
@@ -1,3 +1,36 @@
+2020-09-28  Devin Rousso  <[email protected]>
+
+        [iOS] unable to airplay directly loaded fullscreen video
+        https://bugs.webkit.org/show_bug.cgi?id=216858
+        <rdar://problem/68746321>
+
+        Reviewed by Eric Carlson.
+
+        It's possible that `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` is queried before a
+        "real" `MediaPlayerPrivate` (i.e. not `NullMediaPlayerPrivate`) is initialized through one
+        of the registered `MediaPlayerFactory` "engine"s. It's further possible that the value
+        returned by `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` will change as the new
+        "real" `MediaPlayerPrivate` may have different logic. In this case, the `MediaPlayer`
+        doesn't update its client (and therefore nothing "up" the tree, including the client's
+        clients) with the new `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` value, meaning
+        that the old value will still be used.
+
+        Add piping such that when the `MediaPlayerFactory` "engine" changes, the `MediaPlayer`
+        notifies its client (which is further piped "up" the tree to the client's clients) which
+        eventually causes `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` to be re-evaluated.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::mediaEngineWasUpdated):
+        * page/Page.h:
+        * page/Page.cpp:
+        (WebCore::Page::playbackControlsMediaEngineChanged): Added.
+        * page/ChromeClient.h:
+        (WebCore::ChromeClient::playbackControlsMediaEngineChanged): Added.
+
+        * platform/cocoa/PlaybackSessionModelMediaElement.h:
+        * platform/cocoa/PlaybackSessionModelMediaElement.mm:
+        (WebCore::PlaybackSessionModelMediaElement::mediaEngineChanged): Added.
+
 2020-09-28  Darin Adler  <[email protected]>
 
         REGRESSION (r267329): Crash due to null-dereference of frame pointer in DOMSelection::rangeCount

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (267708 => 267709)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2020-09-28 18:23:58 UTC (rev 267709)
@@ -5050,11 +5050,11 @@
 #endif
 
 #if ENABLE(VIDEO_PRESENTATION_MODE)
-    if (!m_player)
-        return;
-    m_player->setVideoFullscreenFrame(m_videoFullscreenFrame);
-    m_player->setVideoFullscreenGravity(m_videoFullscreenGravity);
-    m_player->setVideoFullscreenLayer(m_videoFullscreenLayer.get());
+    if (m_player) {
+        m_player->setVideoFullscreenFrame(m_videoFullscreenFrame);
+        m_player->setVideoFullscreenGravity(m_videoFullscreenGravity);
+        m_player->setVideoFullscreenLayer(m_videoFullscreenLayer.get());
+    }
 #endif
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
@@ -5064,6 +5064,9 @@
 #if ENABLE(LEGACY_ENCRYPTED_MEDIA) && ENABLE(ENCRYPTED_MEDIA)
     updateShouldContinueAfterNeedKey();
 #endif
+
+    if (auto* page = document().page())
+        page->playbackControlsMediaEngineChanged();
 }
 
 void HTMLMediaElement::mediaPlayerEngineUpdated()

Modified: trunk/Source/WebCore/page/ChromeClient.h (267708 => 267709)


--- trunk/Source/WebCore/page/ChromeClient.h	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebCore/page/ChromeClient.h	2020-09-28 18:23:58 UTC (rev 267709)
@@ -368,6 +368,7 @@
     virtual void enterVideoFullscreenForVideoElement(HTMLVideoElement&, HTMLMediaElementEnums::VideoFullscreenMode, bool standby) { UNUSED_PARAM(standby); }
     virtual void setUpPlaybackControlsManager(HTMLMediaElement&) { }
     virtual void clearPlaybackControlsManager() { }
+    virtual void playbackControlsMediaEngineChanged() { }
 #endif
 
 #if ENABLE(MEDIA_USAGE)

Modified: trunk/Source/WebCore/page/Page.cpp (267708 => 267709)


--- trunk/Source/WebCore/page/Page.cpp	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebCore/page/Page.cpp	2020-09-28 18:23:58 UTC (rev 267709)
@@ -2009,6 +2009,11 @@
 
 #endif
 
+void Page::playbackControlsMediaEngineChanged()
+{
+    chrome().client().playbackControlsMediaEngineChanged();
+}
+
 void Page::setMuted(MediaProducer::MutedStateFlags muted)
 {
     m_mutedState = muted;

Modified: trunk/Source/WebCore/page/Page.h (267708 => 267709)


--- trunk/Source/WebCore/page/Page.h	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebCore/page/Page.h	2020-09-28 18:23:58 UTC (rev 267709)
@@ -642,6 +642,7 @@
     bool isAudioMuted() const { return m_mutedState & MediaProducer::AudioIsMuted; }
     bool isMediaCaptureMuted() const { return m_mutedState & MediaProducer::MediaStreamCaptureIsMuted; };
     void schedulePlaybackControlsManagerUpdate();
+    void playbackControlsMediaEngineChanged();
     WEBCORE_EXPORT void setMuted(MediaProducer::MutedStateFlags);
     WEBCORE_EXPORT void stopMediaCapture();
 

Modified: trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h (267708 => 267709)


--- trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.h	2020-09-28 18:23:58 UTC (rev 267709)
@@ -50,6 +50,8 @@
     WEBCORE_EXPORT void setMediaElement(HTMLMediaElement*);
     HTMLMediaElement* mediaElement() const { return m_mediaElement.get(); }
 
+    WEBCORE_EXPORT void mediaEngineChanged();
+
     WEBCORE_EXPORT void handleEvent(WebCore::ScriptExecutionContext&, WebCore::Event&) final;
     void updateForEventName(const WTF::AtomString&);
     bool operator==(const EventListener& rhs) const final { return static_cast<const WebCore::EventListener*>(this) == &rhs; }

Modified: trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm (267708 => 267709)


--- trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebCore/platform/cocoa/PlaybackSessionModelMediaElement.mm	2020-09-28 18:23:58 UTC (rev 267709)
@@ -117,6 +117,13 @@
         client->isPictureInPictureSupportedChanged(isPictureInPictureSupported());
 }
 
+void PlaybackSessionModelMediaElement::mediaEngineChanged()
+{
+    bool wirelessVideoPlaybackDisabled = this->wirelessVideoPlaybackDisabled();
+    for (auto client : m_clients)
+        client->wirelessVideoPlaybackDisabledChanged(wirelessVideoPlaybackDisabled);
+}
+
 void PlaybackSessionModelMediaElement::handleEvent(WebCore::ScriptExecutionContext&, WebCore::Event& event)
 {
     updateForEventName(event.type());

Modified: trunk/Source/WebKit/ChangeLog (267708 => 267709)


--- trunk/Source/WebKit/ChangeLog	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKit/ChangeLog	2020-09-28 18:23:58 UTC (rev 267709)
@@ -1,3 +1,39 @@
+2020-09-28  Devin Rousso  <[email protected]>
+
+        [iOS] unable to airplay directly loaded fullscreen video
+        https://bugs.webkit.org/show_bug.cgi?id=216858
+        <rdar://problem/68746321>
+
+        Reviewed by Eric Carlson.
+
+        It's possible that `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` is queried before a
+        "real" `MediaPlayerPrivate` (i.e. not `NullMediaPlayerPrivate`) is initialized through one
+        of the registered `MediaPlayerFactory` "engine"s. It's further possible that the value
+        returned by `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` will change as the new
+        "real" `MediaPlayerPrivate` may have different logic. In this case, the `MediaPlayer`
+        doesn't update its client (and therefore nothing "up" the tree, including the client's
+        clients) with the new `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` value, meaning
+        that the old value will still be used.
+
+        Add piping such that when the `MediaPlayerFactory` "engine" changes, the `MediaPlayer`
+        notifies its client (which is further piped "up" the tree to the client's clients) which
+        eventually causes `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` to be re-evaluated.
+
+        * WebProcess/WebCoreSupport/WebChromeClient.h:
+        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+        (WebKit::WebChromeClient::playbackControlsMediaEngineChanged): Added.
+        * WebProcess/cocoa/PlaybackSessionManager.h:
+        * WebProcess/cocoa/PlaybackSessionManager.mm:
+        (WebKit::PlaybackSessionManager::mediaEngineChanged): Added.
+
+        * UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h:
+        * UIProcess/API/Cocoa/WKWebViewTesting.mm:
+        (-[WKWebView _wirelessVideoPlaybackDisabled]): Added.
+        * UIProcess/Cocoa/PlaybackSessionManagerProxy.h:
+        * UIProcess/Cocoa/PlaybackSessionManagerProxy.mm:
+        (WebKit::PlaybackSessionManagerProxy::wirelessVideoPlaybackDisabled): Added.
+        Create additional functions for piping data to tests.
+
 2020-09-28  Youenn Fablet  <[email protected]>
 
         Make sure our calls to AVCaptureDevice requestAccessForMediaType do processing on the main thread

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h (267708 => 267709)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivateForTesting.h	2020-09-28 18:23:58 UTC (rev 267709)
@@ -49,6 +49,7 @@
 
 - (void)_denyNextUserMediaRequest;
 @property (nonatomic, setter=_setMediaCaptureReportingDelayForTesting:) double _mediaCaptureReportingDelayForTesting WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+@property (nonatomic, readonly) BOOL _wirelessVideoPlaybackDisabled;
 
 - (BOOL)_beginBackSwipeForTesting;
 - (BOOL)_completeBackSwipeForTesting;

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm (267708 => 267709)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewTesting.mm	2020-09-28 18:23:58 UTC (rev 267709)
@@ -27,6 +27,7 @@
 #import "WKWebViewPrivateForTesting.h"
 
 #import "AudioSessionRoutingArbitratorProxy.h"
+#import "PlaybackSessionManagerProxy.h"
 #import "UserMediaProcessManager.h"
 #import "ViewGestureController.h"
 #import "WKWebViewIOS.h"
@@ -236,6 +237,15 @@
     _page->setMediaCaptureReportingDelay(Seconds(captureReportingDelay));
 }
 
+- (BOOL)_wirelessVideoPlaybackDisabled
+{
+#if ENABLE(VIDEO_PRESENTATION_MODE)
+    if (auto* playbackSessionManager = _page->playbackSessionManager())
+        return playbackSessionManager->wirelessVideoPlaybackDisabled();
+#endif
+    return false;
+}
+
 - (void)_doAfterProcessingAllPendingMouseEvents:(dispatch_block_t)action
 {
     _page->doAfterProcessingAllPendingMouseEvents([action = "" {

Modified: trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h (267708 => 267709)


--- trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.h	2020-09-28 18:23:58 UTC (rev 267709)
@@ -89,6 +89,8 @@
     void pictureInPictureSupportedChanged(bool);
     void pictureInPictureActiveChanged(bool);
 
+    bool wirelessVideoPlaybackDisabled() const final { return m_wirelessVideoPlaybackDisabled; }
+
 private:
     friend class VideoFullscreenModelContext;
 
@@ -135,7 +137,6 @@
     bool externalPlaybackEnabled() const final { return m_externalPlaybackEnabled; }
     PlaybackSessionModel::ExternalPlaybackTargetType externalPlaybackTargetType() const final { return m_externalPlaybackTargetType; }
     String externalPlaybackLocalizedDeviceName() const final { return m_externalPlaybackLocalizedDeviceName; }
-    bool wirelessVideoPlaybackDisabled() const final { return m_wirelessVideoPlaybackDisabled; }
     bool isMuted() const final { return m_muted; }
     double volume() const final { return m_volume; }
     bool isPictureInPictureSupported() const final { return m_pictureInPictureSupported; }
@@ -180,6 +181,9 @@
     PlatformPlaybackSessionInterface* controlsManagerInterface();
     void requestControlledElementID();
 
+    // For testing.
+    bool wirelessVideoPlaybackDisabled();
+
 private:
     friend class PlaybackSessionModelContext;
     friend class VideoFullscreenManagerProxy;

Modified: trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm (267708 => 267709)


--- trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKit/UIProcess/Cocoa/PlaybackSessionManagerProxy.mm	2020-09-28 18:23:58 UTC (rev 267709)
@@ -580,6 +580,15 @@
         m_page->send(Messages::PlaybackSessionManager::SetPlayingOnSecondScreen(contextId, value));
 }
 
+bool PlaybackSessionManagerProxy::wirelessVideoPlaybackDisabled()
+{
+    auto it = m_contextMap.find(m_controlsManagerContextId);
+    if (it == m_contextMap.end())
+        return true;
+
+    return std::get<0>(it->value)->wirelessVideoPlaybackDisabled();
+}
+
 void PlaybackSessionManagerProxy::requestControlledElementID()
 {
     if (m_controlsManagerContextId)

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (267708 => 267709)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp	2020-09-28 18:23:58 UTC (rev 267709)
@@ -995,6 +995,11 @@
     m_page.playbackSessionManager().clearPlaybackControlsManager();
 }
 
+void WebChromeClient::playbackControlsMediaEngineChanged()
+{
+    m_page.playbackSessionManager().mediaEngineChanged();
+}
+
 #endif
 
 #if ENABLE(MEDIA_USAGE)

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (267708 => 267709)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h	2020-09-28 18:23:58 UTC (rev 267709)
@@ -272,6 +272,7 @@
     void exitVideoFullscreenForVideoElement(WebCore::HTMLVideoElement&) final;
     void setUpPlaybackControlsManager(WebCore::HTMLMediaElement&) final;
     void clearPlaybackControlsManager() final;
+    void playbackControlsMediaEngineChanged() final;
 #endif
 
 #if ENABLE(MEDIA_USAGE)

Modified: trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h (267708 => 267709)


--- trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.h	2020-09-28 18:23:58 UTC (rev 267709)
@@ -104,6 +104,7 @@
 
     void setUpPlaybackControlsManager(WebCore::HTMLMediaElement&);
     void clearPlaybackControlsManager();
+    void mediaEngineChanged();
     PlaybackSessionContextIdentifier contextIdForMediaElement(WebCore::HTMLMediaElement&);
 
     WebCore::HTMLMediaElement* currentPlaybackControlsElement() const;

Modified: trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm (267708 => 267709)


--- trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKit/WebProcess/cocoa/PlaybackSessionManager.mm	2020-09-28 18:23:58 UTC (rev 267709)
@@ -285,6 +285,18 @@
     m_page->send(Messages::PlaybackSessionManagerProxy::ClearPlaybackControlsManager());
 }
 
+void PlaybackSessionManager::mediaEngineChanged()
+{
+    if (!m_controlsManagerContextId)
+        return;
+
+    auto it = m_contextMap.find(m_controlsManagerContextId);
+    if (it == m_contextMap.end())
+        return;
+
+    std::get<0>(it->value)->mediaEngineChanged();
+}
+
 PlaybackSessionContextIdentifier PlaybackSessionManager::contextIdForMediaElement(WebCore::HTMLMediaElement& mediaElement)
 {
     auto addResult = m_mediaElements.ensure(&mediaElement, [&] {

Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (267708 => 267709)


--- trunk/Source/WebKitLegacy/mac/ChangeLog	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog	2020-09-28 18:23:58 UTC (rev 267709)
@@ -1,3 +1,31 @@
+2020-09-28  Devin Rousso  <[email protected]>
+
+        [iOS] unable to airplay directly loaded fullscreen video
+        https://bugs.webkit.org/show_bug.cgi?id=216858
+        <rdar://problem/68746321>
+
+        Reviewed by Eric Carlson.
+
+        It's possible that `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` is queried before a
+        "real" `MediaPlayerPrivate` (i.e. not `NullMediaPlayerPrivate`) is initialized through one
+        of the registered `MediaPlayerFactory` "engine"s. It's further possible that the value
+        returned by `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` will change as the new
+        "real" `MediaPlayerPrivate` may have different logic. In this case, the `MediaPlayer`
+        doesn't update its client (and therefore nothing "up" the tree, including the client's
+        clients) with the new `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` value, meaning
+        that the old value will still be used.
+
+        Add piping such that when the `MediaPlayerFactory` "engine" changes, the `MediaPlayer`
+        notifies its client (which is further piped "up" the tree to the client's clients) which
+        eventually causes `MediaPlayerPrivate::wirelessVideoPlaybackDisabled` to be re-evaluated.
+
+        * WebCoreSupport/WebChromeClient.h:
+        * WebCoreSupport/WebChromeClient.mm:
+        (WebChromeClient::playbackControlsMediaEngineChanged): Added.
+        * WebView/WebViewInternal.h:
+        * WebView/WebView.mm:
+        (-[WebView _playbackControlsMediaEngineChanged]): Added.
+
 2020-09-27  Sam Weinig  <[email protected]>
 
         Fix some typos found by Simon post-review for https://bugs.webkit.org/show_bug.cgi?id=217042

Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h (267708 => 267709)


--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h	2020-09-28 18:23:58 UTC (rev 267709)
@@ -193,6 +193,7 @@
 #if ENABLE(VIDEO) && PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE)
     void setUpPlaybackControlsManager(WebCore::HTMLMediaElement&) final;
     void clearPlaybackControlsManager() final;
+    void playbackControlsMediaEngineChanged() final;
 #endif
 
 #if ENABLE(VIDEO)

Modified: trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm (267708 => 267709)


--- trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm	2020-09-28 18:23:58 UTC (rev 267709)
@@ -1029,6 +1029,11 @@
     [m_webView _clearPlaybackControlsManager];
 }
 
+void WebChromeClient::playbackControlsMediaEngineChanged()
+{
+    [m_webView _playbackControlsMediaEngineChanged];
+}
+
 #endif
 
 #if ENABLE(FULLSCREEN_API)

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebView.mm (267708 => 267709)


--- trunk/Source/WebKitLegacy/mac/WebView/WebView.mm	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebView.mm	2020-09-28 18:23:58 UTC (rev 267709)
@@ -9148,6 +9148,14 @@
     [self updateTouchBar];
 }
 
+- (void)_playbackControlsMediaEngineChanged
+{
+    if (!_private->playbackSessionModel)
+        return;
+
+    _private->playbackSessionModel->mediaEngineChanged();
+}
+
 #endif // PLATFORM(MAC)
 
 #endif // ENABLE(VIDEO_PRESENTATION_MODE)

Modified: trunk/Source/WebKitLegacy/mac/WebView/WebViewInternal.h (267708 => 267709)


--- trunk/Source/WebKitLegacy/mac/WebView/WebViewInternal.h	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebViewInternal.h	2020-09-28 18:23:58 UTC (rev 267709)
@@ -291,6 +291,7 @@
 - (BOOL)_hasActiveVideoForControlsInterface;
 - (void)_setUpPlaybackControlsManagerForMediaElement:(NakedRef<WebCore::HTMLMediaElement>)mediaElement;
 - (void)_clearPlaybackControlsManager;
+- (void)_playbackControlsMediaEngineChanged;
 #endif
 #endif
 #endif

Modified: trunk/Tools/ChangeLog (267708 => 267709)


--- trunk/Tools/ChangeLog	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Tools/ChangeLog	2020-09-28 18:23:58 UTC (rev 267709)
@@ -1,3 +1,16 @@
+2020-09-28  Devin Rousso  <[email protected]>
+
+        [iOS] unable to airplay directly loaded fullscreen video
+        https://bugs.webkit.org/show_bug.cgi?id=216858
+        <rdar://problem/68746321>
+
+        Reviewed by Eric Carlson.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/MediaDocument.mm: Added.
+        (MediaDocument.WirelessPlaybackEnabled):
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+
 2020-09-28  Aakash Jain  <[email protected]>
 
         Notify igalia team about pre-existing test failures and build failures for WPE and GTK queues

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (267708 => 267709)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-09-28 18:23:10 UTC (rev 267708)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2020-09-28 18:23:58 UTC (rev 267709)
@@ -824,6 +824,7 @@
 		93F56DA71E5F9174003EDE84 /* libicucore.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 7C83E0331D0A5F2700FEBCF3 /* libicucore.dylib */; };
 		93F56DA91E5F919D003EDE84 /* WKWebViewSnapshot.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93F56DA81E5F9181003EDE84 /* WKWebViewSnapshot.mm */; };
 		93F7E86F14DC8E5C00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */; };
+		95B6B3B7251EBF2F00FC4382 /* MediaDocument.mm in Sources */ = {isa = PBXBuildFile; fileRef = 95B6B3B6251EBF2F00FC4382 /* MediaDocument.mm */; };
 		9984FACC1CFFAF60008D198C /* WKWebViewTextInput.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9984FACA1CFFAEEE008D198C /* WKWebViewTextInput.mm */; };
 		9984FACE1CFFB090008D198C /* editable-body.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9984FACD1CFFB038008D198C /* editable-body.html */; };
 		9999108B1F393C96008AD455 /* Copying.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9999108A1F393C8B008AD455 /* Copying.mm */; };
@@ -2422,6 +2423,7 @@
 		93F56DA81E5F9181003EDE84 /* WKWebViewSnapshot.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewSnapshot.mm; sourceTree = "<group>"; };
 		93F7E86B14DC8E4D00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFrames.cpp; sourceTree = "<group>"; };
 		93F7E86E14DC8E5B00C84A99 /* NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutFrames_Bundle.cpp; sourceTree = "<group>"; };
+		95B6B3B6251EBF2F00FC4382 /* MediaDocument.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaDocument.mm; sourceTree = "<group>"; };
 		9984FACA1CFFAEEE008D198C /* WKWebViewTextInput.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKWebViewTextInput.mm; sourceTree = "<group>"; };
 		9984FACD1CFFB038008D198C /* editable-body.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "editable-body.html"; sourceTree = "<group>"; };
 		9999108A1F393C8B008AD455 /* Copying.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Copying.mm; sourceTree = "<group>"; };
@@ -3266,6 +3268,7 @@
 				8C10AF96206467770018FD90 /* LocalStoragePersistence.mm */,
 				7A6A2C6F1DCCF87B00C0D085 /* LocalStorageQuirkTest.mm */,
 				07CC7DFD2266330800E39181 /* MediaBufferingPolicy.mm */,
+				95B6B3B6251EBF2F00FC4382 /* MediaDocument.mm */,
 				CD0370E224A44B7A00BA3CAE /* MediaLoading.mm */,
 				51BE9E652376089500B4E117 /* MediaType.mm */,
 				5165FE03201EE617009F7EC3 /* MessagePortProviders.mm */,
@@ -5238,6 +5241,7 @@
 				510A920C24D5275500BFD89C /* LogitechF710.mm in Sources */,
 				CE1866491F72E8F100A0CAB6 /* MarkedText.cpp in Sources */,
 				07CC7DFE2266330900E39181 /* MediaBufferingPolicy.mm in Sources */,
+				95B6B3B7251EBF2F00FC4382 /* MediaDocument.mm in Sources */,
 				CD0370E324A44D9600BA3CAE /* MediaLoading.mm in Sources */,
 				CDA315981ED53651009F60D3 /* MediaPlaybackSleepAssertion.mm in Sources */,
 				CDC9442E1EF1FC080059C3C4 /* MediaStreamTrackDetached.mm in Sources */,

Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaDocument.mm (0 => 267709)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaDocument.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/MediaDocument.mm	2020-09-28 18:23:58 UTC (rev 267709)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#import "PlatformUtilities.h"
+#import "TestWKWebView.h"
+#import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/WKWebViewPrivateForTesting.h>
+#import <wtf/RetainPtr.h>
+
+namespace TestWebKitAPI {
+
+#if ENABLE(VIDEO_PRESENTATION_MODE)
+
+TEST(MediaDocument, WirelessPlaybackEnabled)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
+
+    NSURL *videoURL = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"mp4" subdirectory:@"TestWebKitAPI.resources"];
+    [webView loadFileURL:videoURL allowingReadAccessToURL:videoURL];
+
+    while (![webView _wirelessVideoPlaybackDisabled])
+        Util::sleep(0.1);
+}
+
+#endif // ENABLE(VIDEO_PRESENTATION_MODE)
+
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to