Diff
Modified: branches/safari-602-branch/LayoutTests/ChangeLog (203968 => 203969)
--- branches/safari-602-branch/LayoutTests/ChangeLog 2016-08-01 06:51:45 UTC (rev 203968)
+++ branches/safari-602-branch/LayoutTests/ChangeLog 2016-08-01 06:51:50 UTC (rev 203969)
@@ -1,5 +1,22 @@
2016-07-31 Babak Shafiei <[email protected]>
+ Merge r203931. rdar://problem/27317407
+
+ 2016-07-29 Daniel Bates <[email protected]>
+
+ 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.
+
+ * 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.
+
+2016-07-31 Babak Shafiei <[email protected]>
+
Merge r203924. rdar://problem/27355214
2016-07-29 Zalan Bujtas <[email protected]>
Added: branches/safari-602-branch/LayoutTests/media/non-existent-video-playback-interrupted-expected.txt (0 => 203969)
--- branches/safari-602-branch/LayoutTests/media/non-existent-video-playback-interrupted-expected.txt (rev 0)
+++ branches/safari-602-branch/LayoutTests/media/non-existent-video-playback-interrupted-expected.txt 2016-08-01 06:51:50 UTC (rev 203969)
@@ -0,0 +1,11 @@
+
+RUN(internals.setMediaSessionRestrictions("video", "InterruptedPlaybackNotPermitted"))
+RUN(video.src = ""
+EXPECTED (video.paused == 'true') OK
+RUN(internals.beginMediaSessionInterruption("System"))
+RUN(video.play().then(didResolvePromise).catch(didRejectPromise))
+RUN(internals.endMediaSessionInterruption("MayResumePlaying"))
+Promise rejected. OK
+EXPECTED (error.name == 'NotSupportedError') OK
+END OF TEST
+
Added: branches/safari-602-branch/LayoutTests/media/non-existent-video-playback-interrupted.html (0 => 203969)
--- branches/safari-602-branch/LayoutTests/media/non-existent-video-playback-interrupted.html (rev 0)
+++ branches/safari-602-branch/LayoutTests/media/non-existent-video-playback-interrupted.html 2016-08-01 06:51:50 UTC (rev 203969)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+<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();
+ run('internals.setMediaSessionRestrictions("video", "InterruptedPlaybackNotPermitted")');
+ run('video.src = ""
+ 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>
Added: branches/safari-602-branch/LayoutTests/media/video-playback-interrupted-expected.txt (0 => 203969)
--- branches/safari-602-branch/LayoutTests/media/video-playback-interrupted-expected.txt (rev 0)
+++ branches/safari-602-branch/LayoutTests/media/video-playback-interrupted-expected.txt 2016-08-01 06:51:50 UTC (rev 203969)
@@ -0,0 +1,11 @@
+
+RUN(internals.setMediaSessionRestrictions("video", "InterruptedPlaybackNotPermitted"))
+RUN(video.src = "" "content/test"))
+EXPECTED (video.paused == 'true') OK
+RUN(internals.beginMediaSessionInterruption("System"))
+RUN(video.play().then(didResolvePromise).catch(didRejectPromise))
+RUN(internals.endMediaSessionInterruption("MayResumePlaying"))
+Promise resolved. OK
+EXPECTED (video.paused == 'false') OK
+END OF TEST
+
Added: branches/safari-602-branch/LayoutTests/media/video-playback-interrupted.html (0 => 203969)
--- branches/safari-602-branch/LayoutTests/media/video-playback-interrupted.html (rev 0)
+++ branches/safari-602-branch/LayoutTests/media/video-playback-interrupted.html 2016-08-01 06:51:50 UTC (rev 203969)
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+<script>
+function didResolvePromise()
+{
+ logResult(true, "Promise resolved.");
+ testExpected("video.paused", false);
+
+ // Wait some time before ending the test towards ensuring that we ended the session interruption.
+ endTestLater();
+}
+
+function didRejectPromise(error)
+{
+ logResult(Failed, "Expected promise to be resolved. Was rejected with error " + error);
+
+ // 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();
+ run('internals.setMediaSessionRestrictions("video", "InterruptedPlaybackNotPermitted")');
+ run('video.src = "" "content/test")');
+ 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>
Modified: branches/safari-602-branch/Source/WebCore/ChangeLog (203968 => 203969)
--- branches/safari-602-branch/Source/WebCore/ChangeLog 2016-08-01 06:51:45 UTC (rev 203968)
+++ branches/safari-602-branch/Source/WebCore/ChangeLog 2016-08-01 06:51:50 UTC (rev 203969)
@@ -1,5 +1,40 @@
2016-07-31 Babak Shafiei <[email protected]>
+ Merge r203931. rdar://problem/27317407
+
+ 2016-07-29 Daniel Bates <[email protected]>
+
+ 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.
+
+ 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().
+
+2016-07-31 Babak Shafiei <[email protected]>
+
Merge r203928. rdar://problem/27179484
2016-07-29 Wenson Hsieh <[email protected]>
Modified: branches/safari-602-branch/Source/WebCore/html/HTMLMediaElement.cpp (203968 => 203969)
--- branches/safari-602-branch/Source/WebCore/html/HTMLMediaElement.cpp 2016-08-01 06:51:45 UTC (rev 203968)
+++ branches/safari-602-branch/Source/WebCore/html/HTMLMediaElement.cpp 2016-08-01 06:51:50 UTC (rev 203969)
@@ -3068,8 +3068,10 @@
if (ScriptController::processingUserGestureForMedia())
removeBehaviorsRestrictionsAfterFirstUserGesture();
- if (!playInternal())
+ if (!playInternal()) {
promise.reject(NotAllowedError);
+ return;
+ }
m_pendingPlayPromises.append(WTFMove(promise));
}
@@ -3092,7 +3094,7 @@
if (!m_mediaSession->clientWillBeginPlayback()) {
LOG(Media, " returning because of interruption");
- return false;
+ return true; // Treat as success because we will begin playback on cessation of the interruption.
}
// 4.8.10.9. Playing the media resource