haikuwebkit/LayoutTests/media/non-existent-video-playback...

49 lines
1.2 KiB
HTML
Raw Permalink Normal View History

Crash under HTMLMediaElement::{resolve, reject}PendingPlayPromises() when playback is interrupted https://bugs.webkit.org/show_bug.cgi?id=160366 <rdar://problem/27317407> Reviewed by Eric Carlson. Source/WebCore: Fixes a crash/assertion failure in DeferredWrapper::{resolve, rejectWithValue}() caused by a Promise being settled twice. In particular, if a system interruption occurs when media.play() is invoked the returned Promise may ultimately be settled twice upon cessation of the interruption. A Promise can be settled (resolved) exactly once. When a system interruption occurs media playback is paused and resumes on cessation of the interruption. Currently we also immediately reject the Promise p retuned by media.play() if the interruption occurs during its invocation. So, when we resume playback on cessation of an interruption we try to resolve p again. But a Promise can only be resolved once and hence we violate the assertions that p has both a valid reference to a JSPromiseDeferred object and a reference to the global object of the page. Tests: media/non-existent-video-playback-interrupted.html media/video-playback-interrupted.html * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::play): Modified to reject the Promise and return immediately if playInternal() returns false. (WebCore::HTMLMediaElement::playInternal): Treat an interruption as success and return true so that HTMLMediaElement::play() adds the Promise to the end of the list of pending promises. We treat an interruption as a success because we will resume playback (assuming the media can be loaded and is well-formed) upon cessation of the interruption and therefore can either fulfill or reject the Promise object returned by media.play(). LayoutTests: * media/non-existent-video-playback-interrupted-expected.txt: Added. * media/non-existent-video-playback-interrupted.html: Added. * media/video-playback-interrupted-expected.txt: Added. * media/video-playback-interrupted.html: Added. Canonical link: https://commits.webkit.org/178517@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@203931 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-07-30 00:30:13 +00:00
<!DOCTYPE html>
<html>
<head>
<script src="media-file.js"></script>
<script src="video-test.js"></script>
<script>
var error;
function didResolvePromise()
{
logResult(Failed, "Expected promise to be rejected. Was resolved.");
// Wait some time before ending the test towards ensuring that we ended the session interruption.
endTestLater();
}
function didRejectPromise(e)
{
error = e;
logResult(true, "Promise rejected.");
testExpected("error.name", "NotSupportedError");
// Wait some time before ending the test towards ensuring that we ended the session interruption.
endTestLater();
}
function runTest()
{
if (!window.internals) {
failTest("This test must be run in DumpRenderTree or WebKitTestRunner.");
return;
}
findMediaElement();
Allow multiple playing videos on a page with 'autoplay' and 'playsinline' attributes https://bugs.webkit.org/show_bug.cgi?id=162366 <rdar://problem/28639600> Reviewed by Eric Carlson. Source/WebCore: Tests: media/video-concurrent-visible-playback.html media/video-multiple-concurrent-playback.html Separate out the concept of "video-only" from "video-with-audio" in PlatformMediaSession::MediaType, and only set the ConcurrentPlaybackNotPermitted restriction for "video-with-audio". This allows multiple silent video elements to play back simultaneously. However, the bug in question also shows bad behavior when both concurrent playback and invisible playback are not allowed. Namely, an invisible element will attempt to autoplay, interrupt visible elements, and then fail to play due to it's non-visibility. Add an extra check to canTransitionFromAutoplayToPlay() which asks the session if autoplay is allowed (which will return false if the element is not visible). * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::canTransitionFromAutoplayToPlay): (WebCore::HTMLMediaElement::mediaType): (WebCore::HTMLMediaElement::presentationType): (WebCore::HTMLMediaElement::updateShouldAutoplay): (WebCore::mediaElementIsAllowedToAutoplay): Deleted. * html/MediaElementSession.cpp: (WebCore::MediaElementSession::autoplayPermitted): * html/MediaElementSession.h: * platform/audio/PlatformMediaSession.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::resetRestrictions): * testing/Internals.cpp: (WebCore::Internals::setMediaSessionRestrictions): LayoutTests: * media/content/test-video-only.mp4: Added. * media/non-existent-video-playback-interrupted-expected.txt: * media/non-existent-video-playback-interrupted.html: * media/video-background-playback-expected.txt: * media/video-background-playback.html: * media/video-background-tab-playback-expected.txt: * media/video-background-tab-playback.html: * media/video-concurrent-playback-expected.txt: * media/video-concurrent-playback.html: * media/video-concurrent-visible-playback-expected.txt: Added. * media/video-concurrent-visible-playback.html: Added. * media/video-multiple-concurrent-playback-expected.txt: Added. * media/video-multiple-concurrent-playback.html: Added. * media/video-playback-interrupted-expected.txt: * media/video-playback-interrupted.html: * media/video-restricted-invisible-autoplay-not-allowed.html: Canonical link: https://commits.webkit.org/181931@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208149 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-10-31 16:36:00 +00:00
run('internals.setMediaSessionRestrictions("videoaudio", "InterruptedPlaybackNotPermitted")');
Crash under HTMLMediaElement::{resolve, reject}PendingPlayPromises() when playback is interrupted https://bugs.webkit.org/show_bug.cgi?id=160366 <rdar://problem/27317407> Reviewed by Eric Carlson. Source/WebCore: Fixes a crash/assertion failure in DeferredWrapper::{resolve, rejectWithValue}() caused by a Promise being settled twice. In particular, if a system interruption occurs when media.play() is invoked the returned Promise may ultimately be settled twice upon cessation of the interruption. A Promise can be settled (resolved) exactly once. When a system interruption occurs media playback is paused and resumes on cessation of the interruption. Currently we also immediately reject the Promise p retuned by media.play() if the interruption occurs during its invocation. So, when we resume playback on cessation of an interruption we try to resolve p again. But a Promise can only be resolved once and hence we violate the assertions that p has both a valid reference to a JSPromiseDeferred object and a reference to the global object of the page. Tests: media/non-existent-video-playback-interrupted.html media/video-playback-interrupted.html * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::play): Modified to reject the Promise and return immediately if playInternal() returns false. (WebCore::HTMLMediaElement::playInternal): Treat an interruption as success and return true so that HTMLMediaElement::play() adds the Promise to the end of the list of pending promises. We treat an interruption as a success because we will resume playback (assuming the media can be loaded and is well-formed) upon cessation of the interruption and therefore can either fulfill or reject the Promise object returned by media.play(). LayoutTests: * media/non-existent-video-playback-interrupted-expected.txt: Added. * media/non-existent-video-playback-interrupted.html: Added. * media/video-playback-interrupted-expected.txt: Added. * media/video-playback-interrupted.html: Added. Canonical link: https://commits.webkit.org/178517@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@203931 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-07-30 00:30:13 +00:00
run('video.src = "non-existent.mp4"');
testExpected("video.paused", true);
run('internals.beginMediaSessionInterruption("System")');
run("video.play().then(didResolvePromise).catch(didRejectPromise)");
run('internals.endMediaSessionInterruption("MayResumePlaying")');
}
window.onload = runTest;
</script>
</head>
<body>
<video></video>
</body>
</html>