Skip to content

Commit 2ad2ad3

Browse files
committed
REGRESSION (iOS 17): Chrome crashes in VideoFullscreenModelContext::requestRouteSharingPolicyAndContextUID
https://bugs.webkit.org/show_bug.cgi?id=261676 rdar://80955844 Reviewed by Andy Estes. Because VideoPresentationManagerProxy (nee VideoFullscreenManagerProxy) is refcounted, its lifetime can differ significantly from the WebPageProxy that owns it. When the WebPageProxy invalidates and releases the VideoPresentationManagerProxy, it may still have active operations which expect to call into WebPageProxy, but the m_page pointer has already been reset to null. Add null-checks ahead of all references to m_page and bail out early. * Source/WebKit/UIProcess/Cocoa/VideoPresentationManagerProxy.mm: (WebKit::VideoPresentationModelContext::presentingViewController): (WebKit::VideoPresentationManagerProxy::~VideoPresentationManagerProxy): (WebKit::VideoPresentationManagerProxy::invalidate): (WebKit::VideoPresentationManagerProxy::requestRouteSharingPolicyAndContextUID): (WebKit::VideoPresentationManagerProxy::requestBitmapImageForCurrentTime): (WebKit::VideoPresentationManagerProxy::hasVideoInPictureInPictureDidChange): (WebKit::VideoPresentationManagerProxy::setupFullscreenWithID): (WebKit::VideoPresentationManagerProxy::exitFullscreen): (WebKit::VideoPresentationManagerProxy::preparedToReturnToInline): (WebKit::VideoPresentationManagerProxy::requestFullscreenMode): (WebKit::VideoPresentationManagerProxy::requestUpdateInlineRect): (WebKit::VideoPresentationManagerProxy::requestVideoContentLayer): (WebKit::VideoPresentationManagerProxy::returnVideoContentLayer): (WebKit::VideoPresentationManagerProxy::didSetupFullscreen): (WebKit::VideoPresentationManagerProxy::willExitFullscreen): (WebKit::VideoPresentationManagerProxy::didExitFullscreen): (WebKit::VideoPresentationManagerProxy::didEnterFullscreen): (WebKit::VideoPresentationManagerProxy::failedToEnterFullscreen): (WebKit::VideoPresentationManagerProxy::didCleanupFullscreen): (WebKit::VideoPresentationManagerProxy::setVideoLayerFrame): (WebKit::VideoPresentationManagerProxy::setVideoLayerGravity): (WebKit::VideoPresentationManagerProxy::fullscreenModeChanged): (WebKit::VideoPresentationManagerProxy::fullscreenMayReturnToInline): Canonical link: https://commits.webkit.org/269467@main
1 parent 31ae975 commit 2ad2ad3

File tree

1 file changed

+61
-18
lines changed

1 file changed

+61
-18
lines changed

Source/WebKit/UIProcess/Cocoa/VideoPresentationManagerProxy.mm

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,11 @@ - (BOOL)prefersStatusBarHidden
270270
#if PLATFORM(IOS_FAMILY)
271271
UIViewController *VideoPresentationModelContext::presentingViewController()
272272
{
273-
if (m_manager)
274-
return m_manager->m_page->uiClient().presentingViewController();
273+
if (!m_manager)
274+
return nullptr;
275275

276+
if (auto* page = m_manager->m_page.get())
277+
return page->uiClient().presentingViewController();
276278
return nullptr;
277279
}
278280

@@ -448,18 +450,18 @@ - (BOOL)prefersStatusBarHidden
448450
ALWAYS_LOG(LOGIDENTIFIER);
449451
callCloseCompletionHandlers();
450452

451-
if (!m_page)
452-
return;
453453
invalidate();
454454
}
455455

456456
void VideoPresentationManagerProxy::invalidate()
457457
{
458458
ALWAYS_LOG(LOGIDENTIFIER);
459-
m_page->process().removeMessageReceiver(Messages::VideoPresentationManagerProxy::messageReceiverName(), m_page->webPageID());
460-
m_page = nullptr;
459+
if (m_page) {
460+
m_page->process().removeMessageReceiver(Messages::VideoPresentationManagerProxy::messageReceiverName(), m_page->webPageID());
461+
m_page = nullptr;
462+
}
461463

462-
auto contextMap = WTFMove(m_contextMap);
464+
auto contextMap = std::exchange(m_contextMap, { });
463465
m_clientCounts.clear();
464466

465467
for (auto& [model, interface] : contextMap.values()) {
@@ -523,7 +525,8 @@ - (BOOL)prefersStatusBarHidden
523525

524526
void VideoPresentationManagerProxy::requestRouteSharingPolicyAndContextUID(PlaybackSessionContextIdentifier contextId, CompletionHandler<void(WebCore::RouteSharingPolicy, String)>&& callback)
525527
{
526-
m_page->sendWithAsyncReply(Messages::VideoPresentationManager::RequestRouteSharingPolicyAndContextUID(contextId), WTFMove(callback));
528+
if (m_page)
529+
m_page->sendWithAsyncReply(Messages::VideoPresentationManager::RequestRouteSharingPolicyAndContextUID(contextId), WTFMove(callback));
527530
}
528531

529532
VideoPresentationManagerProxy::ModelInterfaceTuple VideoPresentationManagerProxy::createModelAndInterface(PlaybackSessionContextIdentifier contextId)
@@ -621,6 +624,11 @@ - (BOOL)prefersStatusBarHidden
621624

622625
void VideoPresentationManagerProxy::requestBitmapImageForCurrentTime(PlaybackSessionContextIdentifier identifier, CompletionHandler<void(std::optional<ShareableBitmap::Handle>&&)>&& completionHandler)
623626
{
627+
if (!m_page) {
628+
completionHandler(std::nullopt);
629+
return;
630+
}
631+
624632
RefPtr gpuProcess = GPUProcessProxy::singletonIfCreated();
625633
if (!gpuProcess) {
626634
completionHandler(std::nullopt);
@@ -652,6 +660,8 @@ - (BOOL)prefersStatusBarHidden
652660
{
653661
ALWAYS_LOG(LOGIDENTIFIER, value);
654662
RefPtr page = m_page.get();
663+
if (!page)
664+
return;
655665
page->uiClient().hasVideoInPictureInPictureDidChange(page.get(), value);
656666
m_pipChangeObservers.forEach([value] (auto& observer) { observer(value); });
657667
}
@@ -759,6 +769,9 @@ - (BOOL)prefersStatusBarHidden
759769

760770
void VideoPresentationManagerProxy::setupFullscreenWithID(PlaybackSessionContextIdentifier contextId, WebKit::LayerHostingContextID videoLayerID, const WebCore::FloatRect& screenRect, const WebCore::FloatSize& initialSize, const WebCore::FloatSize& videoDimensions, float hostingDeviceScaleFactor, HTMLMediaElementEnums::VideoFullscreenMode videoFullscreenMode, bool allowsPictureInPicture, bool standby, bool blocksReturnToFullscreenFromPictureInPicture)
761771
{
772+
if (!m_page)
773+
return;
774+
762775
auto& [model, interface] = ensureModelAndInterface(contextId);
763776

764777
// Do not add another refcount for this contextId if the interface is already in
@@ -849,6 +862,11 @@ - (BOOL)prefersStatusBarHidden
849862

850863
void VideoPresentationManagerProxy::exitFullscreen(PlaybackSessionContextIdentifier contextId, WebCore::FloatRect finalRect, CompletionHandler<void(bool)>&& completionHandler)
851864
{
865+
if (!m_page) {
866+
completionHandler(false);
867+
return;
868+
}
869+
852870
ASSERT(m_contextMap.contains(contextId));
853871
if (!m_contextMap.contains(contextId)) {
854872
completionHandler(false);
@@ -942,6 +960,9 @@ - (BOOL)prefersStatusBarHidden
942960

943961
void VideoPresentationManagerProxy::preparedToReturnToInline(PlaybackSessionContextIdentifier contextId, bool visible, WebCore::FloatRect inlineRect)
944962
{
963+
if (!m_page)
964+
return;
965+
945966
m_page->fullscreenMayReturnToInline();
946967

947968
#if !PLATFORM(IOS_FAMILY)
@@ -1010,22 +1031,26 @@ - (BOOL)prefersStatusBarHidden
10101031

10111032
void VideoPresentationManagerProxy::requestFullscreenMode(PlaybackSessionContextIdentifier contextId, WebCore::HTMLMediaElementEnums::VideoFullscreenMode mode, bool finishedWithMedia)
10121033
{
1013-
m_page->send(Messages::VideoPresentationManager::RequestFullscreenMode(contextId, mode, finishedWithMedia));
1034+
if (m_page)
1035+
m_page->send(Messages::VideoPresentationManager::RequestFullscreenMode(contextId, mode, finishedWithMedia));
10141036
}
10151037

10161038
void VideoPresentationManagerProxy::requestUpdateInlineRect(PlaybackSessionContextIdentifier contextId)
10171039
{
1018-
m_page->send(Messages::VideoPresentationManager::RequestUpdateInlineRect(contextId));
1040+
if (m_page)
1041+
m_page->send(Messages::VideoPresentationManager::RequestUpdateInlineRect(contextId));
10191042
}
10201043

10211044
void VideoPresentationManagerProxy::requestVideoContentLayer(PlaybackSessionContextIdentifier contextId)
10221045
{
1023-
m_page->send(Messages::VideoPresentationManager::RequestVideoContentLayer(contextId));
1046+
if (m_page)
1047+
m_page->send(Messages::VideoPresentationManager::RequestVideoContentLayer(contextId));
10241048
}
10251049

10261050
void VideoPresentationManagerProxy::returnVideoContentLayer(PlaybackSessionContextIdentifier contextId)
10271051
{
1028-
m_page->send(Messages::VideoPresentationManager::ReturnVideoContentLayer(contextId));
1052+
if (m_page)
1053+
m_page->send(Messages::VideoPresentationManager::ReturnVideoContentLayer(contextId));
10291054
}
10301055

10311056
void VideoPresentationManagerProxy::returnVideoView(PlaybackSessionContextIdentifier contextId)
@@ -1049,17 +1074,22 @@ - (BOOL)prefersStatusBarHidden
10491074
#if PLATFORM(IOS_FAMILY)
10501075
enterFullscreen(contextId);
10511076
#else
1052-
m_page->send(Messages::VideoPresentationManager::DidSetupFullscreen(contextId));
1077+
if (m_page)
1078+
m_page->send(Messages::VideoPresentationManager::DidSetupFullscreen(contextId));
10531079
#endif
10541080
}
10551081

10561082
void VideoPresentationManagerProxy::willExitFullscreen(PlaybackSessionContextIdentifier contextId)
10571083
{
1058-
m_page->send(Messages::VideoPresentationManager::WillExitFullscreen(contextId));
1084+
if (m_page)
1085+
m_page->send(Messages::VideoPresentationManager::WillExitFullscreen(contextId));
10591086
}
10601087

10611088
void VideoPresentationManagerProxy::didExitFullscreen(PlaybackSessionContextIdentifier contextId)
10621089
{
1090+
if (!m_page)
1091+
return;
1092+
10631093
m_page->send(Messages::VideoPresentationManager::DidExitFullscreen(contextId));
10641094

10651095
#if PLATFORM(IOS_FAMILY)
@@ -1074,6 +1104,9 @@ - (BOOL)prefersStatusBarHidden
10741104

10751105
void VideoPresentationManagerProxy::didEnterFullscreen(PlaybackSessionContextIdentifier contextId, const WebCore::FloatSize& size)
10761106
{
1107+
if (!m_page)
1108+
return;
1109+
10771110
std::optional<FloatSize> optionalSize;
10781111
if (!size.isEmpty())
10791112
optionalSize = size;
@@ -1089,11 +1122,15 @@ - (BOOL)prefersStatusBarHidden
10891122

10901123
void VideoPresentationManagerProxy::failedToEnterFullscreen(PlaybackSessionContextIdentifier contextId)
10911124
{
1092-
m_page->send(Messages::VideoPresentationManager::FailedToEnterFullscreen(contextId));
1125+
if (m_page)
1126+
m_page->send(Messages::VideoPresentationManager::FailedToEnterFullscreen(contextId));
10931127
}
10941128

10951129
void VideoPresentationManagerProxy::didCleanupFullscreen(PlaybackSessionContextIdentifier contextId)
10961130
{
1131+
if (!m_page)
1132+
return;
1133+
10971134
auto& [model, interface] = ensureModelAndInterface(contextId);
10981135

10991136
[model->layerHostView() removeFromSuperview];
@@ -1117,6 +1154,9 @@ - (BOOL)prefersStatusBarHidden
11171154

11181155
void VideoPresentationManagerProxy::setVideoLayerFrame(PlaybackSessionContextIdentifier contextId, WebCore::FloatRect frame)
11191156
{
1157+
if (!m_page)
1158+
return;
1159+
11201160
auto& [model, interface] = ensureModelAndInterface(contextId);
11211161
interface->setCaptionsFrame(CGRectMake(0, 0, frame.width(), frame.height()));
11221162
#if PLATFORM(IOS_FAMILY)
@@ -1132,17 +1172,20 @@ - (BOOL)prefersStatusBarHidden
11321172

11331173
void VideoPresentationManagerProxy::setVideoLayerGravity(PlaybackSessionContextIdentifier contextId, WebCore::MediaPlayerEnums::VideoGravity gravity)
11341174
{
1135-
m_page->send(Messages::VideoPresentationManager::SetVideoLayerGravityEnum(contextId, (unsigned)gravity));
1175+
if (m_page)
1176+
m_page->send(Messages::VideoPresentationManager::SetVideoLayerGravityEnum(contextId, (unsigned)gravity));
11361177
}
11371178

11381179
void VideoPresentationManagerProxy::fullscreenModeChanged(PlaybackSessionContextIdentifier contextId, WebCore::HTMLMediaElementEnums::VideoFullscreenMode mode)
11391180
{
1140-
m_page->send(Messages::VideoPresentationManager::FullscreenModeChanged(contextId, mode));
1181+
if (m_page)
1182+
m_page->send(Messages::VideoPresentationManager::FullscreenModeChanged(contextId, mode));
11411183
}
11421184

11431185
void VideoPresentationManagerProxy::fullscreenMayReturnToInline(PlaybackSessionContextIdentifier contextId)
11441186
{
1145-
m_page->send(Messages::VideoPresentationManager::FullscreenMayReturnToInline(contextId, m_page->isViewVisible()));
1187+
if (m_page)
1188+
m_page->send(Messages::VideoPresentationManager::FullscreenMayReturnToInline(contextId, m_page->isViewVisible()));
11461189
}
11471190

11481191
#endif

0 commit comments

Comments
 (0)