Youtube video pages crash after a couple of minutes
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Jul 2018 21:02:47 +0000 (21:02 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Jul 2018 21:02:47 +0000 (21:02 +0000)
commit380878dda067704802eb3851a04ba784bd7b8fce
tree7fe994338b88798769689450463a39d1a2790509
parentaffc130734cc9dbaf3506c012e222dfa635acd29
Youtube video pages crash after a couple of minutes
https://bugs.webkit.org/show_bug.cgi?id=187316

Reviewed by Antti Koivisto.

Source/WebCore:

The crash was caused by HTMLMediaElement::stopWithoutDestroyingMediaPlayer invoking updatePlaybackControlsManager,
which traverses all media players across different documents including the one in the main frame while its iframe
is getting removed (to update the Touch Bar's media control).

Fixed the bug by making this code async in both stopWithoutDestroyingMediaPlayer and ~HTMLMediaElement. To do this,
this patch moves the timer to update the playback controls manager from HTMLMediaElement to Page since scheduling
a timer owned by HTMLMediaElement in its destructor wouldn't work as the timer would get destructed immediately.

Also replaced the call to clientWillPausePlayback by a call to stopSession in stopWithoutDestroyingMediaPlayer
since the former also updates the layout synchronously via updateNowPlayingInfo; the latter function schedules
a timer via scheduleUpdateNowPlayingInfo instead.

Test: media/remove-video-best-media-element-in-main-frame-crash.html

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::~HTMLMediaElement): Call scheduleUpdatePlaybackControlsManager now that timer has been
moved to Page.
(WebCore::HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager): Made this return a RefPtr instead of
a raw pointer while we're at it.
(WebCore::HTMLMediaElement::clearMediaPlayer): Call scheduleUpdatePlaybackControlsManager.
(WebCore::HTMLMediaElement::stopWithoutDestroyingMediaPlayer): Ditto. Also invoke stopSession instead of
clientWillPausePlayback on MediaSession since clientWillPausePlayback will synchronously try to update the layout.
(WebCore::HTMLMediaElement::contextDestroyed):
(WebCore::HTMLMediaElement::stop):
(WebCore::HTMLMediaElement::scheduleUpdatePlaybackControlsManager):
(WebCore::HTMLMediaElement::updatePlaybackControlsManager): Moved to Page::schedulePlaybackControlsManagerUpdate.
* html/HTMLMediaElement.h:
* page/Page.cpp:
(WebCore::Page::schedulePlaybackControlsManagerUpdate): Added.
* page/Page.h:
* testing/Internals.cpp:
(WebCore::Internals::bestMediaElementForShowingPlaybackControlsManager):
* testing/Internals.h:

Source/WebKitLegacy/mac:

* WebView/WebView.mm:
(-[WebView _preferencesChanged:]):

LayoutTests:

Added a regression test to remove an iframe with a video while there is a main content
which is eligible to be shown in the Touch Bar.

* media/remove-video-best-media-element-in-main-frame-crash-expected.txt: Added.
* media/remove-video-best-media-element-in-main-frame-crash.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233539 268f45cc-cd09-0410-ab3c-d52691b4dbfc
LayoutTests/ChangeLog
LayoutTests/media/remove-video-best-media-element-in-main-frame-crash-expected.txt [new file with mode: 0644]
LayoutTests/media/remove-video-best-media-element-in-main-frame-crash.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/page/Page.cpp
Source/WebCore/page/Page.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebKitLegacy/mac/ChangeLog