Skip to content
Permalink
Browse files
Cleanup fullscreen logic
https://bugs.webkit.org/show_bug.cgi?id=241811

Patch by Youssef Soliman <youssefdevelops@gmail.com> on 2022-06-21
Reviewed by Eric Carlson.

Cleaned up the logic used when entering fullscreen.

* Source/WebCore/html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::enterFullscreen):
* Source/WebCore/page/ChromeClient.h:
(WebCore::ChromeClient::canEnterVideoFullscreen const):
* Source/WebCore/page/Quirks.cpp:
(WebCore::Quirks::allowLayeredFullscreenVideos const):
* Source/WebCore/page/Quirks.h:
* Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::canEnterVideoFullscreen const):
* Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h:
* Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.h:
* Source/WebKit/WebProcess/cocoa/VideoFullscreenManager.mm:
(WebKit::VideoFullscreenManager::canEnterVideoFullscreen const):
(WebKit::VideoFullscreenManager::enterVideoFullscreenForVideoElement):
(WebKit::VideoFullscreenManager::exitVideoFullscreenForVideoElement):
(WebKit::VideoFullscreenManager::exitVideoFullscreenToModeWithoutAnimation):
(WebKit::VideoFullscreenManager::setCurrentlyInFullscreen):
* Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.h:
* Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm:
(WebChromeClient::canEnterVideoFullscreen const):

Canonical link: https://commits.webkit.org/251714@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295709 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
youssefsoli authored and webkit-commit-queue committed Jun 22, 2022
1 parent 187eb34 commit 3ccdbb0d9fd25048b9529b2ea306ca077d4d669c
Showing 10 changed files with 84 additions and 12 deletions.
@@ -6386,20 +6386,21 @@ void HTMLMediaElement::enterFullscreen(VideoFullscreenMode mode)
}
#endif

queueTaskKeepingObjectAlive(*this, TaskSource::MediaElement, [this, mode] {
queueTaskKeepingObjectAlive(*this, TaskSource::MediaElement, [this, mode, logIdentifier = LOGIDENTIFIER] {
if (isContextStopped())
return;

if (document().hidden()) {
ALWAYS_LOG(LOGIDENTIFIER, " returning because document is hidden");
ALWAYS_LOG(logIdentifier, " returning because document is hidden");
m_changingVideoFullscreenMode = false;
return;
}

if (is<HTMLVideoElement>(*this)) {
HTMLVideoElement& asVideo = downcast<HTMLVideoElement>(*this);
if (document().page()->chrome().client().supportsVideoFullscreen(mode)) {
ALWAYS_LOG(LOGIDENTIFIER, "Entering fullscreen mode ", mode, ", m_videoFullscreenStandby = ", m_videoFullscreenStandby);
auto& client = document().page()->chrome().client();
if (client.supportsVideoFullscreen(mode) && client.canEnterVideoFullscreen()) {
ALWAYS_LOG(logIdentifier, "Entering fullscreen mode ", mode, ", m_videoFullscreenStandby = ", m_videoFullscreenStandby);

m_temporarilyAllowingInlinePlaybackAfterFullscreen = false;
if (mode == VideoFullscreenModeStandard)
@@ -6409,7 +6410,7 @@ void HTMLMediaElement::enterFullscreen(VideoFullscreenMode mode)
setFullscreenMode(mode);
configureMediaControls();

document().page()->chrome().client().enterVideoFullscreenForVideoElement(asVideo, m_videoFullscreenMode, m_videoFullscreenStandby);
client.enterVideoFullscreenForVideoElement(asVideo, m_videoFullscreenMode, m_videoFullscreenStandby);
if (m_videoFullscreenStandby)
return;

@@ -415,6 +415,7 @@ class ChromeClient {
virtual GraphicsDeviceAdapter* graphicsDeviceAdapter() const { return nullptr; }
#endif

virtual bool canEnterVideoFullscreen() const { return false; }
virtual bool supportsVideoFullscreen(HTMLMediaElementEnums::VideoFullscreenMode) { return false; }
virtual bool supportsVideoFullscreenStandby() { return false; }

@@ -1481,4 +1481,20 @@ bool Quirks::shouldDisableWebSharePolicy() const
return *m_shouldDisableWebSharePolicy;
}

#if PLATFORM(IOS)
bool Quirks::allowLayeredFullscreenVideos() const
{
if (!needsQuirks())
return false;

if (!m_allowLayeredFullscreenVideos) {
auto domain = RegistrableDomain(m_document->topDocument().url());

m_allowLayeredFullscreenVideos = domain == "espn.com"_s;
}

return *m_allowLayeredFullscreenVideos;
}
#endif

}
@@ -158,7 +158,11 @@ class Quirks {
#endif

bool shouldDisableWebSharePolicy() const;


#if PLATFORM(IOS)
WEBCORE_EXPORT bool allowLayeredFullscreenVideos() const;
#endif

private:
bool needsQuirks() const;

@@ -205,6 +209,9 @@ class Quirks {
mutable std::optional<bool> m_blocksReturnToFullscreenFromPictureInPictureQuirk;
mutable std::optional<bool> m_shouldDisableEndFullscreenEventWhenEnteringPictureInPictureFromFullscreenQuirk;
mutable std::optional<bool> m_shouldDisableWebSharePolicy;
#if PLATFORM(IOS)
mutable std::optional<bool> m_allowLayeredFullscreenVideos;
#endif
};

} // namespace WebCore
@@ -1030,6 +1030,11 @@ void WebChromeClient::prepareForVideoFullscreen()
m_page.videoFullscreenManager();
}

bool WebChromeClient::canEnterVideoFullscreen() const
{
return m_page.videoFullscreenManager().canEnterVideoFullscreen();
}

bool WebChromeClient::supportsVideoFullscreen(HTMLMediaElementEnums::VideoFullscreenMode mode)
{
return m_page.videoFullscreenManager().supportsVideoFullscreen(mode);
@@ -281,6 +281,7 @@ class WebChromeClient final : public WebCore::ChromeClient {

#if ENABLE(VIDEO_PRESENTATION_MODE)
void prepareForVideoFullscreen() final;
bool canEnterVideoFullscreen() const final;
bool supportsVideoFullscreen(WebCore::HTMLMediaElementEnums::VideoFullscreenMode) final;
bool supportsVideoFullscreenStandby() final;
void setMockVideoPresentationModeEnabled(bool) final;
@@ -124,6 +124,7 @@ class VideoFullscreenManager : public RefCounted<VideoFullscreenManager>, privat
void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;

// Interface to WebChromeClient
bool canEnterVideoFullscreen() const;
bool supportsVideoFullscreen(WebCore::HTMLMediaElementEnums::VideoFullscreenMode) const;
bool supportsVideoFullscreenStandby() const;
void enterVideoFullscreenForVideoElement(WebCore::HTMLVideoElement&, WebCore::HTMLMediaElementEnums::VideoFullscreenMode, bool standby);
@@ -166,6 +167,8 @@ class VideoFullscreenManager : public RefCounted<VideoFullscreenManager>, privat
void fullscreenModeChanged(PlaybackSessionContextIdentifier, WebCore::HTMLMediaElementEnums::VideoFullscreenMode);
void fullscreenMayReturnToInline(PlaybackSessionContextIdentifier, bool isPageVisible);
void requestRouteSharingPolicyAndContextUID(PlaybackSessionContextIdentifier, Messages::VideoFullscreenManager::RequestRouteSharingPolicyAndContextUIDAsyncReply&&);

void setCurrentlyInFullscreen(VideoFullscreenInterfaceContext&, bool);

WebPage* m_page;
Ref<PlaybackSessionManager> m_playbackSessionManager;
@@ -174,6 +177,7 @@ class VideoFullscreenManager : public RefCounted<VideoFullscreenManager>, privat
PlaybackSessionContextIdentifier m_controlsManagerContextId;
HashMap<PlaybackSessionContextIdentifier, int> m_clientCounts;
WeakPtr<WebCore::HTMLVideoElement> m_videoElementInPictureInPicture;
bool m_currentlyInFullscreen { false };
};

} // namespace WebKit
@@ -229,6 +229,15 @@ static FloatRect inlineVideoFrame(HTMLVideoElement& element)

#pragma mark Interface to ChromeClient:

bool VideoFullscreenManager::canEnterVideoFullscreen() const
{
#if PLATFORM(IOS)
if (m_currentlyInFullscreen)
return false;
#endif
return true;
}

bool VideoFullscreenManager::supportsVideoFullscreen(WebCore::HTMLMediaElementEnums::VideoFullscreenMode mode) const
{
#if PLATFORM(IOS_FAMILY)
@@ -260,6 +269,18 @@ static FloatRect inlineVideoFrame(HTMLVideoElement& element)
{
ASSERT(m_page);
ASSERT(standby || mode != HTMLMediaElementEnums::VideoFullscreenModeNone);

#if PLATFORM(IOS)
auto allowLayeredFullscreenVideos = videoElement.document().quirks().allowLayeredFullscreenVideos();
if (m_currentlyInFullscreen
&& mode == HTMLMediaElementEnums::VideoFullscreenModeStandard
&& !allowLayeredFullscreenVideos) {
LOG(Fullscreen, "VideoFullscreenManager::enterVideoFullscreenForVideoElement(%p) already in fullscreen, aborting", this);
ASSERT_NOT_REACHED();
return;
}
#endif

LOG(Fullscreen, "VideoFullscreenManager::enterVideoFullscreenForVideoElement(%p)", this);

auto contextId = m_playbackSessionManager->contextIdForMediaElement(videoElement);
@@ -279,10 +300,10 @@ static FloatRect inlineVideoFrame(HTMLVideoElement& element)
auto videoRect = inlineVideoFrame(videoElement);
FloatRect videoLayerFrame = FloatRect(0, 0, videoRect.width(), videoRect.height());

if (mode != HTMLMediaElementEnums::VideoFullscreenModeNone)
interface->setTargetIsFullscreen(true);
else
interface->setTargetIsFullscreen(false);
#if PLATFORM(IOS)
if (!allowLayeredFullscreenVideos)
#endif
setCurrentlyInFullscreen(*interface, mode != HTMLMediaElementEnums::VideoFullscreenModeNone);

if (mode == HTMLMediaElementEnums::VideoFullscreenModePictureInPicture)
m_videoElementInPictureInPicture = videoElement;
@@ -345,7 +366,7 @@ static FloatRect inlineVideoFrame(HTMLVideoElement& element)
m_videoElementInPictureInPicture = nullptr;

auto& interface = ensureInterface(contextId);
interface.setTargetIsFullscreen(false);
protectedThis->setCurrentlyInFullscreen(interface, false);
interface.setAnimationState(VideoFullscreenInterfaceContext::AnimationType::FromFullscreen);
completionHandler(true);
});
@@ -364,7 +385,7 @@ static FloatRect inlineVideoFrame(HTMLVideoElement& element)
auto contextId = m_videoElements.get(&videoElement);
auto& interface = ensureInterface(contextId);

interface.setTargetIsFullscreen(false);
setCurrentlyInFullscreen(interface, false);

// didCleanupFullscreen() will call removeClientForContext() on Mac
#if PLATFORM(IOS_FAMILY)
@@ -597,6 +618,12 @@ static FloatRect inlineVideoFrame(HTMLVideoElement& element)
{
ensureModel(contextId).requestRouteSharingPolicyAndContextUID(WTFMove(reply));
}

void VideoFullscreenManager::setCurrentlyInFullscreen(VideoFullscreenInterfaceContext& interface, bool currentlyInFullscreen)
{
interface.setTargetIsFullscreen(currentlyInFullscreen);
m_currentlyInFullscreen = currentlyInFullscreen;
}

void VideoFullscreenManager::setVideoLayerFrameFenced(PlaybackSessionContextIdentifier contextId, WebCore::FloatRect bounds, const WTF::MachSendRight& machSendRight)
{
@@ -207,6 +207,7 @@ class WebChromeClient : public WebCore::ChromeClient {
#endif

#if ENABLE(VIDEO)
bool canEnterVideoFullscreen() const final;
bool supportsVideoFullscreen(WebCore::HTMLMediaElementEnums::VideoFullscreenMode) final;
#if ENABLE(VIDEO_PRESENTATION_MODE)
void setMockVideoPresentationModeEnabled(bool) final;
@@ -944,6 +944,15 @@ - (void)setIsSelected:(BOOL)isSelected;

#if ENABLE(VIDEO)

bool WebChromeClient::canEnterVideoFullscreen() const
{
#if !PLATFORM(IOS_FAMILY) || HAVE(AVKIT)
return true;
#else
return false;
#endif
}

bool WebChromeClient::supportsVideoFullscreen(HTMLMediaElementEnums::VideoFullscreenMode)
{
#if !PLATFORM(IOS_FAMILY) || HAVE(AVKIT)

0 comments on commit 3ccdbb0

Please sign in to comment.