- Revision
- 269047
- Author
- [email protected]
- Date
- 2020-10-27 10:09:34 -0700 (Tue, 27 Oct 2020)
Log Message
Calling AudioContext.suspend() / resume() while already suspended / running should resolve the promise right away
https://bugs.webkit.org/show_bug.cgi?id=218236
Reviewed by Sam Weinig.
Source/WebCore:
Calling AudioContext.suspend() / resume() while already suspended / running should resolve the promise right
away. This is the behavior in the specification [1][2] and matches Blink / Gecko.
[1] https://www.w3.org/TR/webaudio/#dom-audiocontext-suspend
[2] https://www.w3.org/TR/webaudio/#dom-audiocontext-resume
Tests: webaudio/resume-context-while-running.html
webaudio/suspend-context-while-suspended.html
* Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::suspendRendering):
(WebCore::AudioContext::resumeRendering):
LayoutTests:
Add layout test coverage.
* webaudio/resume-context-while-running-expected.txt: Added.
* webaudio/resume-context-while-running.html: Added.
* webaudio/suspend-context-while-suspended-expected.txt: Added.
* webaudio/suspend-context-while-suspended.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (269046 => 269047)
--- trunk/LayoutTests/ChangeLog 2020-10-27 17:08:50 UTC (rev 269046)
+++ trunk/LayoutTests/ChangeLog 2020-10-27 17:09:34 UTC (rev 269047)
@@ -1,3 +1,17 @@
+2020-10-27 Chris Dumez <[email protected]>
+
+ Calling AudioContext.suspend() / resume() while already suspended / running should resolve the promise right away
+ https://bugs.webkit.org/show_bug.cgi?id=218236
+
+ Reviewed by Sam Weinig.
+
+ Add layout test coverage.
+
+ * webaudio/resume-context-while-running-expected.txt: Added.
+ * webaudio/resume-context-while-running.html: Added.
+ * webaudio/suspend-context-while-suspended-expected.txt: Added.
+ * webaudio/suspend-context-while-suspended.html: Added.
+
2020-10-27 Ryan Haddad <[email protected]>
Web Inspector: console command line API should be exposed to breakpoint conditions/actions
Added: trunk/LayoutTests/webaudio/resume-context-while-running-expected.txt (0 => 269047)
--- trunk/LayoutTests/webaudio/resume-context-while-running-expected.txt (rev 0)
+++ trunk/LayoutTests/webaudio/resume-context-while-running-expected.txt 2020-10-27 17:09:34 UTC (rev 269047)
@@ -0,0 +1,15 @@
+Tests that calling AudioContext.resume() while already running resolves the promise.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Did start rendering
+PASS context.state is "running"
+PASS Calling resume() while running resolved the promise
+PASS context.state is "running"
+PASS Calling resume() while running resolved the promise
+PASS context.state is "running"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/webaudio/resume-context-while-running.html (0 => 269047)
--- trunk/LayoutTests/webaudio/resume-context-while-running.html (rev 0)
+++ trunk/LayoutTests/webaudio/resume-context-while-running.html 2020-10-27 17:09:34 UTC (rev 269047)
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that calling AudioContext.resume() while already running resolves the promise.");
+jsTestIsAsync = true;
+
+function didStartRendering()
+{
+ context._onstatechange_ = null;
+ testPassed("Did start rendering");
+ shouldBeEqualToString("context.state", "running");
+ context.resume().then(() => {
+ testPassed("Calling resume() while running resolved the promise");
+ shouldBeEqualToString("context.state", "running");
+ context.resume().then(() => {
+ testPassed("Calling resume() while running resolved the promise");
+ shouldBeEqualToString("context.state", "running");
+ finishJSTest();
+ }, (e) => {
+ testFailed("Second call to context.resume() unexpectedly threw an exception: " + e);
+ finishJSTest();
+ });
+ }, (e) => {
+ testFailed("First call to context.resume() unexpectedly threw an exception: " + e);
+ finishJSTest();
+ });
+}
+
+let context = new AudioContext;
+var source = context.createConstantSource();
+source.connect(context.destination);
+
+context._onstatechange_ = didStartRendering;
+source.start();
+</script>
+</html>
Added: trunk/LayoutTests/webaudio/suspend-context-while-suspended-expected.txt (0 => 269047)
--- trunk/LayoutTests/webaudio/suspend-context-while-suspended-expected.txt (rev 0)
+++ trunk/LayoutTests/webaudio/suspend-context-while-suspended-expected.txt 2020-10-27 17:09:34 UTC (rev 269047)
@@ -0,0 +1,14 @@
+Tests that calling AudioContext.suspend() while already suspended resolves the promise.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Did start rendering
+PASS context.state is "running"
+PASS context.state is "suspended"
+PASS Calling suspend() while suspended resolved the promise
+PASS context.state is "suspended"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/webaudio/suspend-context-while-suspended.html (0 => 269047)
--- trunk/LayoutTests/webaudio/suspend-context-while-suspended.html (rev 0)
+++ trunk/LayoutTests/webaudio/suspend-context-while-suspended.html 2020-10-27 17:09:34 UTC (rev 269047)
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that calling AudioContext.suspend() while already suspended resolves the promise.");
+jsTestIsAsync = true;
+
+function didStartRendering()
+{
+ context._onstatechange_ = null;
+ testPassed("Did start rendering");
+ shouldBeEqualToString("context.state", "running");
+ context.suspend().then(() => {
+ shouldBeEqualToString("context.state", "suspended");
+ context.suspend().then(() => {
+ testPassed("Calling suspend() while suspended resolved the promise");
+ shouldBeEqualToString("context.state", "suspended");
+ finishJSTest();
+ }, (e) => {
+ testFailed("Second call to context.suspend() unexpectedly threw an exception: " + e);
+ finishJSTest();
+ });
+ }, (e) => {
+ testFailed("First call to context.suspend() unexpectedly threw an exception: " + e);
+ finishJSTest();
+ });
+}
+
+let context = new AudioContext;
+var source = context.createConstantSource();
+source.connect(context.destination);
+
+context._onstatechange_ = didStartRendering;
+source.start();
+</script>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (269046 => 269047)
--- trunk/Source/WebCore/ChangeLog 2020-10-27 17:08:50 UTC (rev 269046)
+++ trunk/Source/WebCore/ChangeLog 2020-10-27 17:09:34 UTC (rev 269047)
@@ -1,3 +1,23 @@
+2020-10-27 Chris Dumez <[email protected]>
+
+ Calling AudioContext.suspend() / resume() while already suspended / running should resolve the promise right away
+ https://bugs.webkit.org/show_bug.cgi?id=218236
+
+ Reviewed by Sam Weinig.
+
+ Calling AudioContext.suspend() / resume() while already suspended / running should resolve the promise right
+ away. This is the behavior in the specification [1][2] and matches Blink / Gecko.
+
+ [1] https://www.w3.org/TR/webaudio/#dom-audiocontext-suspend
+ [2] https://www.w3.org/TR/webaudio/#dom-audiocontext-resume
+
+ Tests: webaudio/resume-context-while-running.html
+ webaudio/suspend-context-while-suspended.html
+
+ * Modules/webaudio/AudioContext.cpp:
+ (WebCore::AudioContext::suspendRendering):
+ (WebCore::AudioContext::resumeRendering):
+
2020-10-27 Chris Lord <[email protected]>
[GLIB] imported/w3c/web-platform-tests/html/canvas/offscreen/line-styles/2d.line.width.transformed.html is a flaky crash
Modified: trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp (269046 => 269047)
--- trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp 2020-10-27 17:08:50 UTC (rev 269046)
+++ trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp 2020-10-27 17:09:34 UTC (rev 269047)
@@ -214,16 +214,18 @@
return;
}
- addReaction(State::Suspended, WTFMove(promise));
m_wasSuspendedByScript = true;
- if (!willPausePlayback())
+ if (!willPausePlayback()) {
+ addReaction(State::Suspended, WTFMove(promise));
return;
+ }
lazyInitialize();
- destinationNode()->suspend([this, protectedThis = makeRef(*this)] {
+ destinationNode()->suspend([this, protectedThis = makeRef(*this), promise = WTFMove(promise)]() mutable {
setState(State::Suspended);
+ promise.resolve();
});
}
@@ -239,20 +241,25 @@
return;
}
- addReaction(State::Running, WTFMove(promise));
m_wasSuspendedByScript = false;
- if (!willBeginPlayback())
+ if (!willBeginPlayback()) {
+ addReaction(State::Running, WTFMove(promise));
return;
+ }
lazyInitialize();
- destinationNode()->resume([this, protectedThis = makeRef(*this)] {
+ destinationNode()->resume([this, protectedThis = makeRef(*this), promise = WTFMove(promise)]() mutable {
// Since we update the state asynchronously, we may have been interrupted after the
// call to resume() and before this lambda runs. In this case, we don't want to
// reset the state to running.
bool interrupted = m_mediaSession->state() == PlatformMediaSession::Interrupted;
setState(interrupted ? State::Interrupted : State::Running);
+ if (interrupted)
+ addReaction(State::Running, WTFMove(promise));
+ else
+ promise.resolve();
});
}