Title: [203969] branches/safari-602-branch

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
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to