haikuwebkit/LayoutTests/webaudio/audiocontext-state.html

125 lines
3.2 KiB
HTML
Raw Permalink Normal View History

[iOS] When Web Audio is interrupted by a phone call, it cannot be restarted. https://bugs.webkit.org/show_bug.cgi?id=143190 Reviewed by Darin Adler. Source/WebCore: Tests: webaudio/audiocontext-state-interrupted.html webaudio/audiocontext-state.html Implement the following methods and properties from the Web Audio spec: close(), suspend(), resume(), onstatechange. AudioContext will take more responsibility for tracking state and interruptions (and AudioDestination will give up that responsibility). This means AudioContext must be a MediaSessionClient, and own its own MediaSession. In return, AudioDestinationIOS and AudioDestinationMac relinquish both. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::AudioContext): Set default values in header. (WebCore::AudioContext::uninitialize): Call setState() instead of setting m_state. (WebCore::AudioContext::addReaction): Added. Append the callback to the appropriate vector for the state. (WebCore::AudioContext::setState): Added. Fire events and resolve the appropriate reaction callbacks for the new state. (WebCore::AudioContext::state): Return a string representing the context's state. (WebCore::AudioContext::stop): Close the event queue. (WebCore::AudioContext::startRendering): Call setState(). (WebCore::AudioContext::fireCompletionEvent): Call setState(). (WebCore::AudioContext::suspendContext): Added. Add reaction callback and call suspend() on the destination node. (WebCore::AudioContext::resumeContext): Added. Add reaction callback and call resume() on the destination node. (WebCore::AudioContext::closeContext): Added. Add reaction callback and call close() on the destination node. (WebCore::AudioContext::suspendPlayback): Added. Suspend playback and set state to interrupted. (WebCore::AudioContext::mayResumePlayback): Added. Conditionally resume playback. * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Added. Create and return a new Promise object. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * Modules/webaudio/AudioContext.idl: Add new methods and properties. Extensive organizational changes were made to AudioContext.h to group instance variables together and add C++11 initializers in their declarations: * Modules/webaudio/AudioContext.h: (WebCore::AudioContext::mediaType): Moved from AudioDestinationNode. (WebCore::AudioContext::presentationType): Ditto. (WebCore::AudioContext::canReceiveRemoteControlCommands): Ditto. (WebCore::AudioContext::didReceiveRemoteControlCommand): Ditto. (WebCore::AudioContext::overrideBackgroundPlaybackRestriction): Ditto. Other changes to support the new AudioContext methods: * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): Add empty default virtual method. (WebCore::AudioDestinationNode::suspend): Ditto. (WebCore::AudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::resume): Added. Pass to AudioDestination. (WebCore::DefaultAudioDestinationNode::suspend): Ditto. (WebCore::DefaultAudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.h: * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::resolve): Add an overload for a nullptr resolve value. * dom/EventNames.h: Added 'statechange'. * dom/ScriptExecutionContext.h: (WebCore::ScriptExecutionContext::Task::Task): Add a constructor which takes a void() callback. Modify MediaSession, AudioSession, and MediaSessionManager to support the new interruption behavior. * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::suspendPlayback): Renamed from pausePlayback(). (WebCore::HTMLMediaElement::mayResumePlayback): Renamed from resumePlayback(). * html/HTMLMediaElement.h: * platform/audio/AudioSession.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/AudioSession.h: * platform/audio/MediaSession.cpp: (WebCore::MediaSession::beginInterruption): pausePlayback() was renamed to suspendPlayback(). (WebCore::MediaSession::endInterruption): Always notify the client, telling it whether to resume. (WebCore::MediaSession::clientWillBeginPlayback): Bail early if reentrant. Check the (new) return value of sessionWillBeginPlayback() and remember to resume once the interruption ends. (WebCore::MediaSession::clientWillPausePlayback): Bail early if reentrant. (WebCore::MediaSession::pauseSession): pausePlayback() was renamed to suspendPlayback(). * platform/audio/MediaSession.h: * platform/audio/MediaSessionManager.cpp: (WebCore::MediaSessionManager::sessionWillBeginPlayback): Return false if not allowed to break interruption or if activating the audio session failed. Otherwise, end the interruption. * platform/audio/MediaSessionManager.h: * platform/audio/ios/AudioDestinationIOS.cpp: (WebCore::AudioDestinationIOS::AudioDestinationIOS): m_mediaSession was removed. (WebCore::AudioDestinationIOS::start): Ditto. * platform/audio/ios/AudioDestinationIOS.h: * platform/audio/ios/AudioSessionIOS.mm: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return false if the AVAudioSession could not be activated. (WebCore::AudioSession::setActive): Deleted. * platform/audio/ios/MediaSessionManagerIOS.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Do not update the now playing info if session playback was blocked. * platform/audio/mac/AudioDestinationMac.cpp: (WebCore::AudioDestinationMac::AudioDestinationMac): m_mediaSession was removed. * platform/audio/mac/AudioDestinationMac.h: * platform/audio/mac/AudioSessionMac.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive(). Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/mac/MediaSessionManagerMac.cpp: (MediaSessionManager::updateSessionState): No longer attempt to activate the session, as this is done MediaSessionManager::sessionWillBeginPlayback(). * testing/Internals.cpp: (WebCore::Internals::setMediaSessionRestrictions): Add "InterruptedPlaybackNotPermitted". LayoutTests: * webaudio/audiocontext-state-expected.txt: Added. * webaudio/audiocontext-state-interrupted-expected.txt: Added. * webaudio/audiocontext-state-interrupted.html: Added. * webaudio/audiocontext-state.html: Added. Canonical link: https://commits.webkit.org/161241@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-30 16:15:00 +00:00
<!DOCTYPE html>
<html>
<head>
Many WebAudio js-tests use waitUntilDone https://bugs.webkit.org/show_bug.cgi?id=172398 Reviewed by Sam Weinig. Corrected the use of js-test harness, updated the tests to use js-test.js instead of js-test-pre.js where possible. * resources/js-test.js: (shouldReject): Copied some funcitonality form js-test-pre.js that wasn't present here. * webaudio/analyser-exception.html: * webaudio/audiobuffer-neuter-expected.txt: * webaudio/audiobuffer-neuter.html: * webaudio/audiobuffersource-channels.html: * webaudio/audiobuffersource-ended-expected.txt: * webaudio/audiobuffersource-ended.html: * webaudio/audiobuffersource-exception.html: * webaudio/audiobuffersource-loop-comprehensive-expected.txt: * webaudio/audiobuffersource-loop-comprehensive.html: * webaudio/audiobuffersource-negative-playbackrate-expected.txt: * webaudio/audiobuffersource-negative-playbackrate-interpolated-expected.txt: * webaudio/audiobuffersource-negative-playbackrate-interpolated-loop-expected.txt: * webaudio/audiobuffersource-negative-playbackrate-interpolated-loop.html: * webaudio/audiobuffersource-negative-playbackrate-interpolated.html: * webaudio/audiobuffersource-negative-playbackrate-loop-expected.txt: * webaudio/audiobuffersource-negative-playbackrate-loop.html: * webaudio/audiobuffersource-negative-playbackrate.html: * webaudio/audiobuffersource-playbackState.html: * webaudio/audiobuffersource-start-expected.txt: * webaudio/audiobuffersource-start.html: * webaudio/audiochannelmerger-basic.html: * webaudio/audiochannelmerger-stereo.html: * webaudio/audiochannelsplitter.html: * webaudio/audiocontext-promise-throwing.html: * webaudio/audiocontext-promise.html: * webaudio/audiocontext-restriction-audiobuffersourcenode-start.html: * webaudio/audiocontext-restriction.html: * webaudio/audiocontext-state-interrupted.html: * webaudio/audiocontext-state.html: * webaudio/audionode-channel-rules.html: * webaudio/audionode-connect-order.html: * webaudio/audionode.html: * webaudio/audioparam-connect-audioratesignal.html: * webaudio/audioparam-summingjunction.html: * webaudio/audioprocessingevent.html: * webaudio/automatic-pull-node.html: * webaudio/biquad-allpass.html: * webaudio/biquad-bandpass.html: * webaudio/biquad-getFrequencyResponse.html: * webaudio/biquad-highpass.html: * webaudio/biquad-highshelf.html: * webaudio/biquad-lowpass.html: * webaudio/biquad-lowshelf.html: * webaudio/biquad-notch.html: * webaudio/biquad-peaking.html: * webaudio/biquadfilternode-basic.html: * webaudio/convolution-mono-mono.html: * webaudio/decode-audio-data-basic.html: * webaudio/decode-audio-data-too-short.html: * webaudio/delaynode-max-default-delay.html: * webaudio/delaynode-max-nondefault-delay.html: * webaudio/delaynode-maxdelay.html: * webaudio/delaynode-maxdelaylimit.html: * webaudio/delaynode-scheduling.html: * webaudio/delaynode.html: * webaudio/distance-exponential.html: * webaudio/distance-inverse.html: * webaudio/distance-linear.html: * webaudio/dynamicscompressor-basic.html: * webaudio/javascriptaudionode-downmix8-2channel-input.html: * webaudio/javascriptaudionode-upmix2-8channel-input.html: * webaudio/javascriptaudionode-zero-input-channels.html: * webaudio/javascriptaudionode.html: * webaudio/mediaelementaudiosourcenode.html: * webaudio/oscillator-basic.html: * webaudio/oscillator-ended-expected.txt: * webaudio/oscillator-ended.html: * webaudio/page-canstartmedia.html: * webaudio/panner-equalpower-stereo.html: * webaudio/panner-equalpower.html: * webaudio/panner-loop.html: * webaudio/pannernode-basic.html: * webaudio/realtimeanalyser-fft-scaling.html: * webaudio/realtimeanalyser-fft-sizing.html: * webaudio/resources/audiobuffersource-testing.js: (checkAllTests): * webaudio/sample-accurate-scheduling.html: * webaudio/stereo2mono-down-mixing.html: * webaudio/test-basic.html: * webaudio/waveshaper.html: Canonical link: https://commits.webkit.org/189368@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@217243 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-05-22 20:49:12 +00:00
<script src="../resources/js-test.js"></script>
[iOS] When Web Audio is interrupted by a phone call, it cannot be restarted. https://bugs.webkit.org/show_bug.cgi?id=143190 Reviewed by Darin Adler. Source/WebCore: Tests: webaudio/audiocontext-state-interrupted.html webaudio/audiocontext-state.html Implement the following methods and properties from the Web Audio spec: close(), suspend(), resume(), onstatechange. AudioContext will take more responsibility for tracking state and interruptions (and AudioDestination will give up that responsibility). This means AudioContext must be a MediaSessionClient, and own its own MediaSession. In return, AudioDestinationIOS and AudioDestinationMac relinquish both. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::AudioContext): Set default values in header. (WebCore::AudioContext::uninitialize): Call setState() instead of setting m_state. (WebCore::AudioContext::addReaction): Added. Append the callback to the appropriate vector for the state. (WebCore::AudioContext::setState): Added. Fire events and resolve the appropriate reaction callbacks for the new state. (WebCore::AudioContext::state): Return a string representing the context's state. (WebCore::AudioContext::stop): Close the event queue. (WebCore::AudioContext::startRendering): Call setState(). (WebCore::AudioContext::fireCompletionEvent): Call setState(). (WebCore::AudioContext::suspendContext): Added. Add reaction callback and call suspend() on the destination node. (WebCore::AudioContext::resumeContext): Added. Add reaction callback and call resume() on the destination node. (WebCore::AudioContext::closeContext): Added. Add reaction callback and call close() on the destination node. (WebCore::AudioContext::suspendPlayback): Added. Suspend playback and set state to interrupted. (WebCore::AudioContext::mayResumePlayback): Added. Conditionally resume playback. * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Added. Create and return a new Promise object. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * Modules/webaudio/AudioContext.idl: Add new methods and properties. Extensive organizational changes were made to AudioContext.h to group instance variables together and add C++11 initializers in their declarations: * Modules/webaudio/AudioContext.h: (WebCore::AudioContext::mediaType): Moved from AudioDestinationNode. (WebCore::AudioContext::presentationType): Ditto. (WebCore::AudioContext::canReceiveRemoteControlCommands): Ditto. (WebCore::AudioContext::didReceiveRemoteControlCommand): Ditto. (WebCore::AudioContext::overrideBackgroundPlaybackRestriction): Ditto. Other changes to support the new AudioContext methods: * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): Add empty default virtual method. (WebCore::AudioDestinationNode::suspend): Ditto. (WebCore::AudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::resume): Added. Pass to AudioDestination. (WebCore::DefaultAudioDestinationNode::suspend): Ditto. (WebCore::DefaultAudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.h: * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::resolve): Add an overload for a nullptr resolve value. * dom/EventNames.h: Added 'statechange'. * dom/ScriptExecutionContext.h: (WebCore::ScriptExecutionContext::Task::Task): Add a constructor which takes a void() callback. Modify MediaSession, AudioSession, and MediaSessionManager to support the new interruption behavior. * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::suspendPlayback): Renamed from pausePlayback(). (WebCore::HTMLMediaElement::mayResumePlayback): Renamed from resumePlayback(). * html/HTMLMediaElement.h: * platform/audio/AudioSession.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/AudioSession.h: * platform/audio/MediaSession.cpp: (WebCore::MediaSession::beginInterruption): pausePlayback() was renamed to suspendPlayback(). (WebCore::MediaSession::endInterruption): Always notify the client, telling it whether to resume. (WebCore::MediaSession::clientWillBeginPlayback): Bail early if reentrant. Check the (new) return value of sessionWillBeginPlayback() and remember to resume once the interruption ends. (WebCore::MediaSession::clientWillPausePlayback): Bail early if reentrant. (WebCore::MediaSession::pauseSession): pausePlayback() was renamed to suspendPlayback(). * platform/audio/MediaSession.h: * platform/audio/MediaSessionManager.cpp: (WebCore::MediaSessionManager::sessionWillBeginPlayback): Return false if not allowed to break interruption or if activating the audio session failed. Otherwise, end the interruption. * platform/audio/MediaSessionManager.h: * platform/audio/ios/AudioDestinationIOS.cpp: (WebCore::AudioDestinationIOS::AudioDestinationIOS): m_mediaSession was removed. (WebCore::AudioDestinationIOS::start): Ditto. * platform/audio/ios/AudioDestinationIOS.h: * platform/audio/ios/AudioSessionIOS.mm: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return false if the AVAudioSession could not be activated. (WebCore::AudioSession::setActive): Deleted. * platform/audio/ios/MediaSessionManagerIOS.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Do not update the now playing info if session playback was blocked. * platform/audio/mac/AudioDestinationMac.cpp: (WebCore::AudioDestinationMac::AudioDestinationMac): m_mediaSession was removed. * platform/audio/mac/AudioDestinationMac.h: * platform/audio/mac/AudioSessionMac.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive(). Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/mac/MediaSessionManagerMac.cpp: (MediaSessionManager::updateSessionState): No longer attempt to activate the session, as this is done MediaSessionManager::sessionWillBeginPlayback(). * testing/Internals.cpp: (WebCore::Internals::setMediaSessionRestrictions): Add "InterruptedPlaybackNotPermitted". LayoutTests: * webaudio/audiocontext-state-expected.txt: Added. * webaudio/audiocontext-state-interrupted-expected.txt: Added. * webaudio/audiocontext-state-interrupted.html: Added. * webaudio/audiocontext-state.html: Added. Canonical link: https://commits.webkit.org/161241@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-30 16:15:00 +00:00
<script type="text/javascript" src="resources/audio-testing.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
description('Basic tests for AudioNode API.');
var context = null;
var node = null;
[GPUProcess] Use async IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination https://bugs.webkit.org/show_bug.cgi?id=218251 Reviewed by Geoffrey Garen. Source/WebCore: DefaultAudioDestinationNode::resume() / suspend() were already asynchronous operations. However, they expected AudioDestination::start() / stop() to finish synchronously and would simply call their completion handler asynchronously. Instead, we now make AudioDestination::start() / stop() asynchronous as well. This allows us to use asynchronous IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination. As a result of this change, I had to make AudioDestinationNode::startRendering() asynchronous as well since it uses AudioDestination::start() internally. As an improvement, the completion handler to AudioDestinationNode's startRendering() / resume() / suspend() is now provided with an exception in cases where they fail. This allows the call sites to properly deal with such errors instead of assuming things were successsful. No new tests, no Web-facing beahvior change. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::suspendRendering): (WebCore::AudioContext::resumeRendering): (WebCore::AudioContext::startRendering): (WebCore::AudioContext::mayResumePlayback): (WebCore::AudioContext::suspendPlayback): * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): (WebCore::AudioDestinationNode::suspend): (WebCore::AudioDestinationNode::close): * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::startRendering): (WebCore::DefaultAudioDestinationNode::resume): (WebCore::DefaultAudioDestinationNode::suspend): (WebCore::DefaultAudioDestinationNode::close): * Modules/webaudio/DefaultAudioDestinationNode.h: * Modules/webaudio/OfflineAudioContext.cpp: (WebCore::OfflineAudioContext::startOfflineRendering): (WebCore::OfflineAudioContext::resumeOfflineRendering): * Modules/webaudio/OfflineAudioDestinationNode.cpp: (WebCore::OfflineAudioDestinationNode::startRendering): * Modules/webaudio/OfflineAudioDestinationNode.h: * platform/audio/AudioDestination.h: (WebCore::AudioDestination::start): (WebCore::AudioDestination::stop): * platform/audio/cocoa/AudioDestinationCocoa.cpp: (WebCore::AudioDestinationCocoa::start): (WebCore::AudioDestinationCocoa::stop): * platform/audio/cocoa/AudioDestinationCocoa.h: * platform/audio/gstreamer/AudioDestinationGStreamer.cpp: (WebCore::AudioDestinationGStreamer::start): (WebCore::AudioDestinationGStreamer::stop): * platform/audio/gstreamer/AudioDestinationGStreamer.h: * platform/mock/MockAudioDestinationCocoa.cpp: (WebCore::MockAudioDestinationCocoa::start): (WebCore::MockAudioDestinationCocoa::stop): * platform/mock/MockAudioDestinationCocoa.h: Source/WebKit: Use async IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination. * GPUProcess/media/RemoteAudioDestinationManager.messages.in: * WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp: (WebKit::RemoteAudioDestinationProxy::start): (WebKit::RemoteAudioDestinationProxy::stop): * WebProcess/GPU/media/RemoteAudioDestinationProxy.h: LayoutTests: * webaudio/audiocontext-state.html: Update existing test which incorrectly expected the AudioContext's state to become "running" synchronously after connecting a source node. The state switches to "running" asynchronously now. It is up to the user agent if and when the audio context starts autoplaying so this should be an acceptable behavior change. Canonical link: https://commits.webkit.org/230961@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@269073 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-10-27 21:46:21 +00:00
function onAudioContextAutoStart()
{
context.onstatechange = null;
shouldBeEqualToString('context.state', 'running');
debug('Calling context.suspend()');
context.suspend().then(suspendSucceeded, suspendFailed);
}
[iOS] When Web Audio is interrupted by a phone call, it cannot be restarted. https://bugs.webkit.org/show_bug.cgi?id=143190 Reviewed by Darin Adler. Source/WebCore: Tests: webaudio/audiocontext-state-interrupted.html webaudio/audiocontext-state.html Implement the following methods and properties from the Web Audio spec: close(), suspend(), resume(), onstatechange. AudioContext will take more responsibility for tracking state and interruptions (and AudioDestination will give up that responsibility). This means AudioContext must be a MediaSessionClient, and own its own MediaSession. In return, AudioDestinationIOS and AudioDestinationMac relinquish both. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::AudioContext): Set default values in header. (WebCore::AudioContext::uninitialize): Call setState() instead of setting m_state. (WebCore::AudioContext::addReaction): Added. Append the callback to the appropriate vector for the state. (WebCore::AudioContext::setState): Added. Fire events and resolve the appropriate reaction callbacks for the new state. (WebCore::AudioContext::state): Return a string representing the context's state. (WebCore::AudioContext::stop): Close the event queue. (WebCore::AudioContext::startRendering): Call setState(). (WebCore::AudioContext::fireCompletionEvent): Call setState(). (WebCore::AudioContext::suspendContext): Added. Add reaction callback and call suspend() on the destination node. (WebCore::AudioContext::resumeContext): Added. Add reaction callback and call resume() on the destination node. (WebCore::AudioContext::closeContext): Added. Add reaction callback and call close() on the destination node. (WebCore::AudioContext::suspendPlayback): Added. Suspend playback and set state to interrupted. (WebCore::AudioContext::mayResumePlayback): Added. Conditionally resume playback. * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Added. Create and return a new Promise object. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * Modules/webaudio/AudioContext.idl: Add new methods and properties. Extensive organizational changes were made to AudioContext.h to group instance variables together and add C++11 initializers in their declarations: * Modules/webaudio/AudioContext.h: (WebCore::AudioContext::mediaType): Moved from AudioDestinationNode. (WebCore::AudioContext::presentationType): Ditto. (WebCore::AudioContext::canReceiveRemoteControlCommands): Ditto. (WebCore::AudioContext::didReceiveRemoteControlCommand): Ditto. (WebCore::AudioContext::overrideBackgroundPlaybackRestriction): Ditto. Other changes to support the new AudioContext methods: * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): Add empty default virtual method. (WebCore::AudioDestinationNode::suspend): Ditto. (WebCore::AudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::resume): Added. Pass to AudioDestination. (WebCore::DefaultAudioDestinationNode::suspend): Ditto. (WebCore::DefaultAudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.h: * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::resolve): Add an overload for a nullptr resolve value. * dom/EventNames.h: Added 'statechange'. * dom/ScriptExecutionContext.h: (WebCore::ScriptExecutionContext::Task::Task): Add a constructor which takes a void() callback. Modify MediaSession, AudioSession, and MediaSessionManager to support the new interruption behavior. * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::suspendPlayback): Renamed from pausePlayback(). (WebCore::HTMLMediaElement::mayResumePlayback): Renamed from resumePlayback(). * html/HTMLMediaElement.h: * platform/audio/AudioSession.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/AudioSession.h: * platform/audio/MediaSession.cpp: (WebCore::MediaSession::beginInterruption): pausePlayback() was renamed to suspendPlayback(). (WebCore::MediaSession::endInterruption): Always notify the client, telling it whether to resume. (WebCore::MediaSession::clientWillBeginPlayback): Bail early if reentrant. Check the (new) return value of sessionWillBeginPlayback() and remember to resume once the interruption ends. (WebCore::MediaSession::clientWillPausePlayback): Bail early if reentrant. (WebCore::MediaSession::pauseSession): pausePlayback() was renamed to suspendPlayback(). * platform/audio/MediaSession.h: * platform/audio/MediaSessionManager.cpp: (WebCore::MediaSessionManager::sessionWillBeginPlayback): Return false if not allowed to break interruption or if activating the audio session failed. Otherwise, end the interruption. * platform/audio/MediaSessionManager.h: * platform/audio/ios/AudioDestinationIOS.cpp: (WebCore::AudioDestinationIOS::AudioDestinationIOS): m_mediaSession was removed. (WebCore::AudioDestinationIOS::start): Ditto. * platform/audio/ios/AudioDestinationIOS.h: * platform/audio/ios/AudioSessionIOS.mm: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return false if the AVAudioSession could not be activated. (WebCore::AudioSession::setActive): Deleted. * platform/audio/ios/MediaSessionManagerIOS.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Do not update the now playing info if session playback was blocked. * platform/audio/mac/AudioDestinationMac.cpp: (WebCore::AudioDestinationMac::AudioDestinationMac): m_mediaSession was removed. * platform/audio/mac/AudioDestinationMac.h: * platform/audio/mac/AudioSessionMac.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive(). Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/mac/MediaSessionManagerMac.cpp: (MediaSessionManager::updateSessionState): No longer attempt to activate the session, as this is done MediaSessionManager::sessionWillBeginPlayback(). * testing/Internals.cpp: (WebCore::Internals::setMediaSessionRestrictions): Add "InterruptedPlaybackNotPermitted". LayoutTests: * webaudio/audiocontext-state-expected.txt: Added. * webaudio/audiocontext-state-interrupted-expected.txt: Added. * webaudio/audiocontext-state-interrupted.html: Added. * webaudio/audiocontext-state.html: Added. Canonical link: https://commits.webkit.org/161241@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-30 16:15:00 +00:00
function runTest() {
window.jsTestIsAsync = true;
Turn off the legacy prefixed WebAudio API https://bugs.webkit.org/show_bug.cgi?id=216886 Reviewed by Sam Weinig. LayoutTests/imported/w3c: * web-platform-tests/webaudio/historical-expected.txt: Rebaseline test that is now passing. Source/WebCore: Turn off the legacy prefixed WebAudio API, now that the modern unprefixed API has been enabled in r267488. No new tests, rebaselined existing tests. * Modules/webaudio/AudioBufferSourceNode.idl: Make sure legacy constants get unexposed if the PrefixedWebAudio setting is disabled. * bindings/scripts/CodeGeneratorJS.pm: (GenerateImplementation): (GetRuntimeEnabledStaticProperties): * bindings/scripts/test/JS/JSTestConditionalIncludes.cpp: (WebCore::JSTestConditionalIncludesConstructor::initializeProperties): (WebCore::JSTestConditionalIncludesPrototype::finishCreation): * bindings/scripts/test/JS/JSTestEnabledBySetting.cpp: (WebCore::JSTestEnabledBySettingConstructor::prototypeForStructure): (WebCore::JSTestEnabledBySettingConstructor::initializeProperties): (WebCore::JSTestEnabledBySettingPrototype::finishCreation): * bindings/scripts/test/TestEnabledBySetting.idl: Add support for using [EnabledBySetting=X] on constants. Source/WebKit: Turn off the legacy prefixed WebAudio API, now that the modern unprefixed API has been enabled in r267488. * Shared/WebPreferencesInternal.yaml: Source/WebKitLegacy/mac: Turn off the legacy prefixed WebAudio API, now that the modern unprefixed API has been enabled in r267488. * WebView/WebView.mm: (-[WebView _preferencesChanged:]): LayoutTests: Port existing layout tests from the prefixed WebAudio API to the new unprefixed version. * fast/history/page-cache-closed-audiocontext.html: * fast/history/page-cache-running-audiocontext.html: * fast/history/page-cache-suspended-audiocontext.html: * fast/mediastream/getUserMedia-webaudio.html: * fast/mediastream/media-devices-enumerate-devices.html: * fast/mediastream/mediastreamtrack-audio-clone.html: * fast/mediastream/mock-media-source-webaudio.html: * http/tests/security/webaudio-render-remote-audio-allowed-crossorigin.html: * http/tests/security/webaudio-render-remote-audio-blocked-no-crossorigin.html: * http/wpt/mediarecorder/MediaRecorder-onremovetrack.html: * http/wpt/webaudio/resources/audiocontext-stopped-iframe.html: * platform/ios/webaudio/realtimeanalyser-fft-sizing-expected.txt: * resources/testharnessreport.js: * webaudio/analyser-exception.html: * webaudio/audiobuffer-crash-expected.txt: * webaudio/audiobuffer-crash.html: * webaudio/audiobuffer-expected.txt: * webaudio/audiobuffer-neuter.html: * webaudio/audiobuffer.html: * webaudio/audiobuffersource-channels-expected.txt: * webaudio/audiobuffersource-channels.html: * webaudio/audiobuffersource-ended.html: * webaudio/audiobuffersource-multi-channels.html: * webaudio/audiobuffersource-negative-playbackrate-interpolated-loop.html: * webaudio/audiobuffersource-negative-playbackrate-interpolated.html: * webaudio/audiobuffersource-negative-playbackrate-loop.html: * webaudio/audiobuffersource-negative-playbackrate.html: * webaudio/audiobuffersource-not-gced-until-ended.html: * webaudio/audiobuffersource-playbackState-expected.txt: Removed. * webaudio/audiobuffersource-playbackState.html: Removed. * webaudio/audiobuffersource-playbackrate.html: * webaudio/audiobuffersource-start.html: * webaudio/audiobuffersource.html: * webaudio/audiobuffersourcenode-legacy-api-expected.txt: * webaudio/audiobuffersourcenode-legacy-api.html: * webaudio/audiochannelmerger-basic.html: * webaudio/audiochannelmerger-stereo.html: * webaudio/audiochannelsplitter.html: * webaudio/audiocontext-promise-throwing-expected.txt: * webaudio/audiocontext-promise-throwing.html: * webaudio/audiocontext-promise.html: * webaudio/audiocontext-restriction-audiobuffersourcenode-start.html: * webaudio/audiocontext-restriction.html: * webaudio/audiocontext-state-interrupted.html: * webaudio/audiocontext-state.html: * webaudio/audionode-connect-order.html: * webaudio/audionode.html: * webaudio/audioparam-connect-audioratesignal.html: * webaudio/audioparam-summingjunction.html: * webaudio/audioprocessingevent.html: * webaudio/automatic-pull-node.html: * webaudio/convolution-mono-mono.html: * webaudio/convolver-channels.html: * webaudio/convolver-setBuffer-different-samplerate.html: * webaudio/convolver-setBuffer-null.html: * webaudio/createMediaStreamSource-null-expected.txt: * webaudio/createMediaStreamSource-null.html: * webaudio/decode-audio-data-basic-expected.txt: * webaudio/decode-audio-data-basic.html: * webaudio/decode-audio-data-too-short.html: * webaudio/delaynode-max-default-delay.html: * webaudio/delaynode-max-nondefault-delay.html: * webaudio/delaynode-maxdelay.html: * webaudio/delaynode-maxdelaylimit.html: * webaudio/delaynode-scheduling.html: * webaudio/delaynode.html: * webaudio/distance-exponential.html: * webaudio/distance-inverse.html: * webaudio/distance-linear.html: * webaudio/dynamicscompressor-basic.html: * webaudio/finished-audio-buffer-source-nodes-should-be-collectable.html: * webaudio/gain-basic.html: * webaudio/gain.html: * webaudio/mediaelementaudiosourcenode-expected.txt: * webaudio/mediaelementaudiosourcenode-gc.html: * webaudio/mediaelementaudiosourcenode.html: * webaudio/mixing.html: * webaudio/offlineaudiocontext-gc.html: * webaudio/offlineaudiocontext-restriction.html: * webaudio/oscillatornode-legacy-api-expected.txt: * webaudio/oscillatornode-legacy-api.html: * webaudio/page-canstartmedia.html: * webaudio/panner-equalpower-stereo.html: * webaudio/panner-equalpower.html: * webaudio/prefixed-pannernode-basic-expected.txt: Removed. * webaudio/prefixed-pannernode-basic.html: Removed. * webaudio/realtimeanalyser-fft-sizing-expected.txt: * webaudio/realtimeanalyser-fft-sizing.html: * webaudio/resources/audio-codec-test.js: (runDecodingTest): * webaudio/resources/audiobuffersource-ended-detached-frame-iframe.html: * webaudio/resources/audioparam-testing-legacy.js: (createAudioGraphAndTest): * webaudio/resources/compatibility.js: Removed. * webaudio/resources/javascriptaudionode-testing.js: (runJSNodeTest): * webaudio/resources/oscillator-testing-legacy.js: (generateExponentialOscillatorSweep): * webaudio/sample-accurate-scheduling.html: * webaudio/silence-after-playback.html: * webaudio/silent-audio-interrupted-in-background.html: * webaudio/stereo2mono-down-mixing.html: * webaudio/test-basic.html: * webaudio/up-mixing-mono-51.html: * webaudio/up-mixing-mono-stereo.html: * webaudio/up-mixing-stereo-51.html: * webaudio/waveshaper.html: * webaudio/web-audio-is-playing.html: * webaudio/webaudio-gc.html: * webaudio/webkitofflineaudiocontext-startRendering-crash-expected.txt: * webaudio/webkitofflineaudiocontext-startRendering-crash.html: * webrtc/audio-peer-connection-g722.html: * webrtc/audio-peer-connection-webaudio.html: * webrtc/clone-audio-track.html: * webrtc/getUserMedia-webaudio-autoplay.html: * webrtc/peer-connection-audio-mute.html: * webrtc/peer-connection-audio-mute2.html: * webrtc/peer-connection-createMediaStreamDestination.html: * webrtc/peer-connection-remote-audio-mute.html: * webrtc/peer-connection-remote-audio-mute2.html: * webrtc/routines.js: Canonical link: https://commits.webkit.org/229688@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@267504 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-09-23 22:48:05 +00:00
context = new AudioContext();
[GPUProcess] Use async IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination https://bugs.webkit.org/show_bug.cgi?id=218251 Reviewed by Geoffrey Garen. Source/WebCore: DefaultAudioDestinationNode::resume() / suspend() were already asynchronous operations. However, they expected AudioDestination::start() / stop() to finish synchronously and would simply call their completion handler asynchronously. Instead, we now make AudioDestination::start() / stop() asynchronous as well. This allows us to use asynchronous IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination. As a result of this change, I had to make AudioDestinationNode::startRendering() asynchronous as well since it uses AudioDestination::start() internally. As an improvement, the completion handler to AudioDestinationNode's startRendering() / resume() / suspend() is now provided with an exception in cases where they fail. This allows the call sites to properly deal with such errors instead of assuming things were successsful. No new tests, no Web-facing beahvior change. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::suspendRendering): (WebCore::AudioContext::resumeRendering): (WebCore::AudioContext::startRendering): (WebCore::AudioContext::mayResumePlayback): (WebCore::AudioContext::suspendPlayback): * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): (WebCore::AudioDestinationNode::suspend): (WebCore::AudioDestinationNode::close): * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::startRendering): (WebCore::DefaultAudioDestinationNode::resume): (WebCore::DefaultAudioDestinationNode::suspend): (WebCore::DefaultAudioDestinationNode::close): * Modules/webaudio/DefaultAudioDestinationNode.h: * Modules/webaudio/OfflineAudioContext.cpp: (WebCore::OfflineAudioContext::startOfflineRendering): (WebCore::OfflineAudioContext::resumeOfflineRendering): * Modules/webaudio/OfflineAudioDestinationNode.cpp: (WebCore::OfflineAudioDestinationNode::startRendering): * Modules/webaudio/OfflineAudioDestinationNode.h: * platform/audio/AudioDestination.h: (WebCore::AudioDestination::start): (WebCore::AudioDestination::stop): * platform/audio/cocoa/AudioDestinationCocoa.cpp: (WebCore::AudioDestinationCocoa::start): (WebCore::AudioDestinationCocoa::stop): * platform/audio/cocoa/AudioDestinationCocoa.h: * platform/audio/gstreamer/AudioDestinationGStreamer.cpp: (WebCore::AudioDestinationGStreamer::start): (WebCore::AudioDestinationGStreamer::stop): * platform/audio/gstreamer/AudioDestinationGStreamer.h: * platform/mock/MockAudioDestinationCocoa.cpp: (WebCore::MockAudioDestinationCocoa::start): (WebCore::MockAudioDestinationCocoa::stop): * platform/mock/MockAudioDestinationCocoa.h: Source/WebKit: Use async IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination. * GPUProcess/media/RemoteAudioDestinationManager.messages.in: * WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp: (WebKit::RemoteAudioDestinationProxy::start): (WebKit::RemoteAudioDestinationProxy::stop): * WebProcess/GPU/media/RemoteAudioDestinationProxy.h: LayoutTests: * webaudio/audiocontext-state.html: Update existing test which incorrectly expected the AudioContext's state to become "running" synchronously after connecting a source node. The state switches to "running" asynchronously now. It is up to the user agent if and when the audio context starts autoplaying so this should be an acceptable behavior change. Canonical link: https://commits.webkit.org/230961@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@269073 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-10-27 21:46:21 +00:00
context.onstatechange = onAudioContextAutoStart;
[iOS] When Web Audio is interrupted by a phone call, it cannot be restarted. https://bugs.webkit.org/show_bug.cgi?id=143190 Reviewed by Darin Adler. Source/WebCore: Tests: webaudio/audiocontext-state-interrupted.html webaudio/audiocontext-state.html Implement the following methods and properties from the Web Audio spec: close(), suspend(), resume(), onstatechange. AudioContext will take more responsibility for tracking state and interruptions (and AudioDestination will give up that responsibility). This means AudioContext must be a MediaSessionClient, and own its own MediaSession. In return, AudioDestinationIOS and AudioDestinationMac relinquish both. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::AudioContext): Set default values in header. (WebCore::AudioContext::uninitialize): Call setState() instead of setting m_state. (WebCore::AudioContext::addReaction): Added. Append the callback to the appropriate vector for the state. (WebCore::AudioContext::setState): Added. Fire events and resolve the appropriate reaction callbacks for the new state. (WebCore::AudioContext::state): Return a string representing the context's state. (WebCore::AudioContext::stop): Close the event queue. (WebCore::AudioContext::startRendering): Call setState(). (WebCore::AudioContext::fireCompletionEvent): Call setState(). (WebCore::AudioContext::suspendContext): Added. Add reaction callback and call suspend() on the destination node. (WebCore::AudioContext::resumeContext): Added. Add reaction callback and call resume() on the destination node. (WebCore::AudioContext::closeContext): Added. Add reaction callback and call close() on the destination node. (WebCore::AudioContext::suspendPlayback): Added. Suspend playback and set state to interrupted. (WebCore::AudioContext::mayResumePlayback): Added. Conditionally resume playback. * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Added. Create and return a new Promise object. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * Modules/webaudio/AudioContext.idl: Add new methods and properties. Extensive organizational changes were made to AudioContext.h to group instance variables together and add C++11 initializers in their declarations: * Modules/webaudio/AudioContext.h: (WebCore::AudioContext::mediaType): Moved from AudioDestinationNode. (WebCore::AudioContext::presentationType): Ditto. (WebCore::AudioContext::canReceiveRemoteControlCommands): Ditto. (WebCore::AudioContext::didReceiveRemoteControlCommand): Ditto. (WebCore::AudioContext::overrideBackgroundPlaybackRestriction): Ditto. Other changes to support the new AudioContext methods: * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): Add empty default virtual method. (WebCore::AudioDestinationNode::suspend): Ditto. (WebCore::AudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::resume): Added. Pass to AudioDestination. (WebCore::DefaultAudioDestinationNode::suspend): Ditto. (WebCore::DefaultAudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.h: * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::resolve): Add an overload for a nullptr resolve value. * dom/EventNames.h: Added 'statechange'. * dom/ScriptExecutionContext.h: (WebCore::ScriptExecutionContext::Task::Task): Add a constructor which takes a void() callback. Modify MediaSession, AudioSession, and MediaSessionManager to support the new interruption behavior. * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::suspendPlayback): Renamed from pausePlayback(). (WebCore::HTMLMediaElement::mayResumePlayback): Renamed from resumePlayback(). * html/HTMLMediaElement.h: * platform/audio/AudioSession.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/AudioSession.h: * platform/audio/MediaSession.cpp: (WebCore::MediaSession::beginInterruption): pausePlayback() was renamed to suspendPlayback(). (WebCore::MediaSession::endInterruption): Always notify the client, telling it whether to resume. (WebCore::MediaSession::clientWillBeginPlayback): Bail early if reentrant. Check the (new) return value of sessionWillBeginPlayback() and remember to resume once the interruption ends. (WebCore::MediaSession::clientWillPausePlayback): Bail early if reentrant. (WebCore::MediaSession::pauseSession): pausePlayback() was renamed to suspendPlayback(). * platform/audio/MediaSession.h: * platform/audio/MediaSessionManager.cpp: (WebCore::MediaSessionManager::sessionWillBeginPlayback): Return false if not allowed to break interruption or if activating the audio session failed. Otherwise, end the interruption. * platform/audio/MediaSessionManager.h: * platform/audio/ios/AudioDestinationIOS.cpp: (WebCore::AudioDestinationIOS::AudioDestinationIOS): m_mediaSession was removed. (WebCore::AudioDestinationIOS::start): Ditto. * platform/audio/ios/AudioDestinationIOS.h: * platform/audio/ios/AudioSessionIOS.mm: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return false if the AVAudioSession could not be activated. (WebCore::AudioSession::setActive): Deleted. * platform/audio/ios/MediaSessionManagerIOS.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Do not update the now playing info if session playback was blocked. * platform/audio/mac/AudioDestinationMac.cpp: (WebCore::AudioDestinationMac::AudioDestinationMac): m_mediaSession was removed. * platform/audio/mac/AudioDestinationMac.h: * platform/audio/mac/AudioSessionMac.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive(). Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/mac/MediaSessionManagerMac.cpp: (MediaSessionManager::updateSessionState): No longer attempt to activate the session, as this is done MediaSessionManager::sessionWillBeginPlayback(). * testing/Internals.cpp: (WebCore::Internals::setMediaSessionRestrictions): Add "InterruptedPlaybackNotPermitted". LayoutTests: * webaudio/audiocontext-state-expected.txt: Added. * webaudio/audiocontext-state-interrupted-expected.txt: Added. * webaudio/audiocontext-state-interrupted.html: Added. * webaudio/audiocontext-state.html: Added. Canonical link: https://commits.webkit.org/161241@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-30 16:15:00 +00:00
[GPUProcess] Use async IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination https://bugs.webkit.org/show_bug.cgi?id=218251 Reviewed by Geoffrey Garen. Source/WebCore: DefaultAudioDestinationNode::resume() / suspend() were already asynchronous operations. However, they expected AudioDestination::start() / stop() to finish synchronously and would simply call their completion handler asynchronously. Instead, we now make AudioDestination::start() / stop() asynchronous as well. This allows us to use asynchronous IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination. As a result of this change, I had to make AudioDestinationNode::startRendering() asynchronous as well since it uses AudioDestination::start() internally. As an improvement, the completion handler to AudioDestinationNode's startRendering() / resume() / suspend() is now provided with an exception in cases where they fail. This allows the call sites to properly deal with such errors instead of assuming things were successsful. No new tests, no Web-facing beahvior change. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::suspendRendering): (WebCore::AudioContext::resumeRendering): (WebCore::AudioContext::startRendering): (WebCore::AudioContext::mayResumePlayback): (WebCore::AudioContext::suspendPlayback): * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): (WebCore::AudioDestinationNode::suspend): (WebCore::AudioDestinationNode::close): * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::startRendering): (WebCore::DefaultAudioDestinationNode::resume): (WebCore::DefaultAudioDestinationNode::suspend): (WebCore::DefaultAudioDestinationNode::close): * Modules/webaudio/DefaultAudioDestinationNode.h: * Modules/webaudio/OfflineAudioContext.cpp: (WebCore::OfflineAudioContext::startOfflineRendering): (WebCore::OfflineAudioContext::resumeOfflineRendering): * Modules/webaudio/OfflineAudioDestinationNode.cpp: (WebCore::OfflineAudioDestinationNode::startRendering): * Modules/webaudio/OfflineAudioDestinationNode.h: * platform/audio/AudioDestination.h: (WebCore::AudioDestination::start): (WebCore::AudioDestination::stop): * platform/audio/cocoa/AudioDestinationCocoa.cpp: (WebCore::AudioDestinationCocoa::start): (WebCore::AudioDestinationCocoa::stop): * platform/audio/cocoa/AudioDestinationCocoa.h: * platform/audio/gstreamer/AudioDestinationGStreamer.cpp: (WebCore::AudioDestinationGStreamer::start): (WebCore::AudioDestinationGStreamer::stop): * platform/audio/gstreamer/AudioDestinationGStreamer.h: * platform/mock/MockAudioDestinationCocoa.cpp: (WebCore::MockAudioDestinationCocoa::start): (WebCore::MockAudioDestinationCocoa::stop): * platform/mock/MockAudioDestinationCocoa.h: Source/WebKit: Use async IPC for RemoteAudioDestinationManager's StartAudioDestination / StopAudioDestination. * GPUProcess/media/RemoteAudioDestinationManager.messages.in: * WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp: (WebKit::RemoteAudioDestinationProxy::start): (WebKit::RemoteAudioDestinationProxy::stop): * WebProcess/GPU/media/RemoteAudioDestinationProxy.h: LayoutTests: * webaudio/audiocontext-state.html: Update existing test which incorrectly expected the AudioContext's state to become "running" synchronously after connecting a source node. The state switches to "running" asynchronously now. It is up to the user agent if and when the audio context starts autoplaying so this should be an acceptable behavior change. Canonical link: https://commits.webkit.org/230961@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@269073 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-10-27 21:46:21 +00:00
shouldBeEqualToString('context.state', 'suspended');
[iOS] When Web Audio is interrupted by a phone call, it cannot be restarted. https://bugs.webkit.org/show_bug.cgi?id=143190 Reviewed by Darin Adler. Source/WebCore: Tests: webaudio/audiocontext-state-interrupted.html webaudio/audiocontext-state.html Implement the following methods and properties from the Web Audio spec: close(), suspend(), resume(), onstatechange. AudioContext will take more responsibility for tracking state and interruptions (and AudioDestination will give up that responsibility). This means AudioContext must be a MediaSessionClient, and own its own MediaSession. In return, AudioDestinationIOS and AudioDestinationMac relinquish both. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::AudioContext): Set default values in header. (WebCore::AudioContext::uninitialize): Call setState() instead of setting m_state. (WebCore::AudioContext::addReaction): Added. Append the callback to the appropriate vector for the state. (WebCore::AudioContext::setState): Added. Fire events and resolve the appropriate reaction callbacks for the new state. (WebCore::AudioContext::state): Return a string representing the context's state. (WebCore::AudioContext::stop): Close the event queue. (WebCore::AudioContext::startRendering): Call setState(). (WebCore::AudioContext::fireCompletionEvent): Call setState(). (WebCore::AudioContext::suspendContext): Added. Add reaction callback and call suspend() on the destination node. (WebCore::AudioContext::resumeContext): Added. Add reaction callback and call resume() on the destination node. (WebCore::AudioContext::closeContext): Added. Add reaction callback and call close() on the destination node. (WebCore::AudioContext::suspendPlayback): Added. Suspend playback and set state to interrupted. (WebCore::AudioContext::mayResumePlayback): Added. Conditionally resume playback. * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Added. Create and return a new Promise object. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * Modules/webaudio/AudioContext.idl: Add new methods and properties. Extensive organizational changes were made to AudioContext.h to group instance variables together and add C++11 initializers in their declarations: * Modules/webaudio/AudioContext.h: (WebCore::AudioContext::mediaType): Moved from AudioDestinationNode. (WebCore::AudioContext::presentationType): Ditto. (WebCore::AudioContext::canReceiveRemoteControlCommands): Ditto. (WebCore::AudioContext::didReceiveRemoteControlCommand): Ditto. (WebCore::AudioContext::overrideBackgroundPlaybackRestriction): Ditto. Other changes to support the new AudioContext methods: * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): Add empty default virtual method. (WebCore::AudioDestinationNode::suspend): Ditto. (WebCore::AudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::resume): Added. Pass to AudioDestination. (WebCore::DefaultAudioDestinationNode::suspend): Ditto. (WebCore::DefaultAudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.h: * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::resolve): Add an overload for a nullptr resolve value. * dom/EventNames.h: Added 'statechange'. * dom/ScriptExecutionContext.h: (WebCore::ScriptExecutionContext::Task::Task): Add a constructor which takes a void() callback. Modify MediaSession, AudioSession, and MediaSessionManager to support the new interruption behavior. * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::suspendPlayback): Renamed from pausePlayback(). (WebCore::HTMLMediaElement::mayResumePlayback): Renamed from resumePlayback(). * html/HTMLMediaElement.h: * platform/audio/AudioSession.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/AudioSession.h: * platform/audio/MediaSession.cpp: (WebCore::MediaSession::beginInterruption): pausePlayback() was renamed to suspendPlayback(). (WebCore::MediaSession::endInterruption): Always notify the client, telling it whether to resume. (WebCore::MediaSession::clientWillBeginPlayback): Bail early if reentrant. Check the (new) return value of sessionWillBeginPlayback() and remember to resume once the interruption ends. (WebCore::MediaSession::clientWillPausePlayback): Bail early if reentrant. (WebCore::MediaSession::pauseSession): pausePlayback() was renamed to suspendPlayback(). * platform/audio/MediaSession.h: * platform/audio/MediaSessionManager.cpp: (WebCore::MediaSessionManager::sessionWillBeginPlayback): Return false if not allowed to break interruption or if activating the audio session failed. Otherwise, end the interruption. * platform/audio/MediaSessionManager.h: * platform/audio/ios/AudioDestinationIOS.cpp: (WebCore::AudioDestinationIOS::AudioDestinationIOS): m_mediaSession was removed. (WebCore::AudioDestinationIOS::start): Ditto. * platform/audio/ios/AudioDestinationIOS.h: * platform/audio/ios/AudioSessionIOS.mm: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return false if the AVAudioSession could not be activated. (WebCore::AudioSession::setActive): Deleted. * platform/audio/ios/MediaSessionManagerIOS.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Do not update the now playing info if session playback was blocked. * platform/audio/mac/AudioDestinationMac.cpp: (WebCore::AudioDestinationMac::AudioDestinationMac): m_mediaSession was removed. * platform/audio/mac/AudioDestinationMac.h: * platform/audio/mac/AudioSessionMac.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive(). Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/mac/MediaSessionManagerMac.cpp: (MediaSessionManager::updateSessionState): No longer attempt to activate the session, as this is done MediaSessionManager::sessionWillBeginPlayback(). * testing/Internals.cpp: (WebCore::Internals::setMediaSessionRestrictions): Add "InterruptedPlaybackNotPermitted". LayoutTests: * webaudio/audiocontext-state-expected.txt: Added. * webaudio/audiocontext-state-interrupted-expected.txt: Added. * webaudio/audiocontext-state-interrupted.html: Added. * webaudio/audiocontext-state.html: Added. Canonical link: https://commits.webkit.org/161241@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-30 16:15:00 +00:00
node = context.createBufferSource();
evalAndLog('node.connect(context.destination)');
}
function suspendFailed() {
testFailed('context.suspend() promise rejected');
finishJSTest();
}
function suspendSucceeded(value) {
if (typeof value != 'undefined') {
testFailed('context.suspend() promise should not resolve with a value.');
finishJSTest();
return;
}
[iOS] When Web Audio is interrupted by a phone call, it cannot be restarted. https://bugs.webkit.org/show_bug.cgi?id=143190 Reviewed by Darin Adler. Source/WebCore: Tests: webaudio/audiocontext-state-interrupted.html webaudio/audiocontext-state.html Implement the following methods and properties from the Web Audio spec: close(), suspend(), resume(), onstatechange. AudioContext will take more responsibility for tracking state and interruptions (and AudioDestination will give up that responsibility). This means AudioContext must be a MediaSessionClient, and own its own MediaSession. In return, AudioDestinationIOS and AudioDestinationMac relinquish both. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::AudioContext): Set default values in header. (WebCore::AudioContext::uninitialize): Call setState() instead of setting m_state. (WebCore::AudioContext::addReaction): Added. Append the callback to the appropriate vector for the state. (WebCore::AudioContext::setState): Added. Fire events and resolve the appropriate reaction callbacks for the new state. (WebCore::AudioContext::state): Return a string representing the context's state. (WebCore::AudioContext::stop): Close the event queue. (WebCore::AudioContext::startRendering): Call setState(). (WebCore::AudioContext::fireCompletionEvent): Call setState(). (WebCore::AudioContext::suspendContext): Added. Add reaction callback and call suspend() on the destination node. (WebCore::AudioContext::resumeContext): Added. Add reaction callback and call resume() on the destination node. (WebCore::AudioContext::closeContext): Added. Add reaction callback and call close() on the destination node. (WebCore::AudioContext::suspendPlayback): Added. Suspend playback and set state to interrupted. (WebCore::AudioContext::mayResumePlayback): Added. Conditionally resume playback. * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Added. Create and return a new Promise object. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * Modules/webaudio/AudioContext.idl: Add new methods and properties. Extensive organizational changes were made to AudioContext.h to group instance variables together and add C++11 initializers in their declarations: * Modules/webaudio/AudioContext.h: (WebCore::AudioContext::mediaType): Moved from AudioDestinationNode. (WebCore::AudioContext::presentationType): Ditto. (WebCore::AudioContext::canReceiveRemoteControlCommands): Ditto. (WebCore::AudioContext::didReceiveRemoteControlCommand): Ditto. (WebCore::AudioContext::overrideBackgroundPlaybackRestriction): Ditto. Other changes to support the new AudioContext methods: * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): Add empty default virtual method. (WebCore::AudioDestinationNode::suspend): Ditto. (WebCore::AudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::resume): Added. Pass to AudioDestination. (WebCore::DefaultAudioDestinationNode::suspend): Ditto. (WebCore::DefaultAudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.h: * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::resolve): Add an overload for a nullptr resolve value. * dom/EventNames.h: Added 'statechange'. * dom/ScriptExecutionContext.h: (WebCore::ScriptExecutionContext::Task::Task): Add a constructor which takes a void() callback. Modify MediaSession, AudioSession, and MediaSessionManager to support the new interruption behavior. * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::suspendPlayback): Renamed from pausePlayback(). (WebCore::HTMLMediaElement::mayResumePlayback): Renamed from resumePlayback(). * html/HTMLMediaElement.h: * platform/audio/AudioSession.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/AudioSession.h: * platform/audio/MediaSession.cpp: (WebCore::MediaSession::beginInterruption): pausePlayback() was renamed to suspendPlayback(). (WebCore::MediaSession::endInterruption): Always notify the client, telling it whether to resume. (WebCore::MediaSession::clientWillBeginPlayback): Bail early if reentrant. Check the (new) return value of sessionWillBeginPlayback() and remember to resume once the interruption ends. (WebCore::MediaSession::clientWillPausePlayback): Bail early if reentrant. (WebCore::MediaSession::pauseSession): pausePlayback() was renamed to suspendPlayback(). * platform/audio/MediaSession.h: * platform/audio/MediaSessionManager.cpp: (WebCore::MediaSessionManager::sessionWillBeginPlayback): Return false if not allowed to break interruption or if activating the audio session failed. Otherwise, end the interruption. * platform/audio/MediaSessionManager.h: * platform/audio/ios/AudioDestinationIOS.cpp: (WebCore::AudioDestinationIOS::AudioDestinationIOS): m_mediaSession was removed. (WebCore::AudioDestinationIOS::start): Ditto. * platform/audio/ios/AudioDestinationIOS.h: * platform/audio/ios/AudioSessionIOS.mm: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return false if the AVAudioSession could not be activated. (WebCore::AudioSession::setActive): Deleted. * platform/audio/ios/MediaSessionManagerIOS.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Do not update the now playing info if session playback was blocked. * platform/audio/mac/AudioDestinationMac.cpp: (WebCore::AudioDestinationMac::AudioDestinationMac): m_mediaSession was removed. * platform/audio/mac/AudioDestinationMac.h: * platform/audio/mac/AudioSessionMac.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive(). Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/mac/MediaSessionManagerMac.cpp: (MediaSessionManager::updateSessionState): No longer attempt to activate the session, as this is done MediaSessionManager::sessionWillBeginPlayback(). * testing/Internals.cpp: (WebCore::Internals::setMediaSessionRestrictions): Add "InterruptedPlaybackNotPermitted". LayoutTests: * webaudio/audiocontext-state-expected.txt: Added. * webaudio/audiocontext-state-interrupted-expected.txt: Added. * webaudio/audiocontext-state-interrupted.html: Added. * webaudio/audiocontext-state.html: Added. Canonical link: https://commits.webkit.org/161241@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-30 16:15:00 +00:00
testPassed('context.suspend() promise resolved');
shouldBe('context.state', '"suspended"');
debug('Calling context.resume()');
context.resume().then(resumeSucceeded, resumeFailed);
}
function resumeFailed() {
testFailed('context.resume() promise rejected');
finishJSTest();
}
function resumeSucceeded(value) {
if (typeof value != 'undefined') {
testFailed('context.resume() promise should not resolve with a value.');
finishJSTest();
return;
}
[iOS] When Web Audio is interrupted by a phone call, it cannot be restarted. https://bugs.webkit.org/show_bug.cgi?id=143190 Reviewed by Darin Adler. Source/WebCore: Tests: webaudio/audiocontext-state-interrupted.html webaudio/audiocontext-state.html Implement the following methods and properties from the Web Audio spec: close(), suspend(), resume(), onstatechange. AudioContext will take more responsibility for tracking state and interruptions (and AudioDestination will give up that responsibility). This means AudioContext must be a MediaSessionClient, and own its own MediaSession. In return, AudioDestinationIOS and AudioDestinationMac relinquish both. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::AudioContext): Set default values in header. (WebCore::AudioContext::uninitialize): Call setState() instead of setting m_state. (WebCore::AudioContext::addReaction): Added. Append the callback to the appropriate vector for the state. (WebCore::AudioContext::setState): Added. Fire events and resolve the appropriate reaction callbacks for the new state. (WebCore::AudioContext::state): Return a string representing the context's state. (WebCore::AudioContext::stop): Close the event queue. (WebCore::AudioContext::startRendering): Call setState(). (WebCore::AudioContext::fireCompletionEvent): Call setState(). (WebCore::AudioContext::suspendContext): Added. Add reaction callback and call suspend() on the destination node. (WebCore::AudioContext::resumeContext): Added. Add reaction callback and call resume() on the destination node. (WebCore::AudioContext::closeContext): Added. Add reaction callback and call close() on the destination node. (WebCore::AudioContext::suspendPlayback): Added. Suspend playback and set state to interrupted. (WebCore::AudioContext::mayResumePlayback): Added. Conditionally resume playback. * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Added. Create and return a new Promise object. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * Modules/webaudio/AudioContext.idl: Add new methods and properties. Extensive organizational changes were made to AudioContext.h to group instance variables together and add C++11 initializers in their declarations: * Modules/webaudio/AudioContext.h: (WebCore::AudioContext::mediaType): Moved from AudioDestinationNode. (WebCore::AudioContext::presentationType): Ditto. (WebCore::AudioContext::canReceiveRemoteControlCommands): Ditto. (WebCore::AudioContext::didReceiveRemoteControlCommand): Ditto. (WebCore::AudioContext::overrideBackgroundPlaybackRestriction): Ditto. Other changes to support the new AudioContext methods: * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): Add empty default virtual method. (WebCore::AudioDestinationNode::suspend): Ditto. (WebCore::AudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::resume): Added. Pass to AudioDestination. (WebCore::DefaultAudioDestinationNode::suspend): Ditto. (WebCore::DefaultAudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.h: * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::resolve): Add an overload for a nullptr resolve value. * dom/EventNames.h: Added 'statechange'. * dom/ScriptExecutionContext.h: (WebCore::ScriptExecutionContext::Task::Task): Add a constructor which takes a void() callback. Modify MediaSession, AudioSession, and MediaSessionManager to support the new interruption behavior. * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::suspendPlayback): Renamed from pausePlayback(). (WebCore::HTMLMediaElement::mayResumePlayback): Renamed from resumePlayback(). * html/HTMLMediaElement.h: * platform/audio/AudioSession.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/AudioSession.h: * platform/audio/MediaSession.cpp: (WebCore::MediaSession::beginInterruption): pausePlayback() was renamed to suspendPlayback(). (WebCore::MediaSession::endInterruption): Always notify the client, telling it whether to resume. (WebCore::MediaSession::clientWillBeginPlayback): Bail early if reentrant. Check the (new) return value of sessionWillBeginPlayback() and remember to resume once the interruption ends. (WebCore::MediaSession::clientWillPausePlayback): Bail early if reentrant. (WebCore::MediaSession::pauseSession): pausePlayback() was renamed to suspendPlayback(). * platform/audio/MediaSession.h: * platform/audio/MediaSessionManager.cpp: (WebCore::MediaSessionManager::sessionWillBeginPlayback): Return false if not allowed to break interruption or if activating the audio session failed. Otherwise, end the interruption. * platform/audio/MediaSessionManager.h: * platform/audio/ios/AudioDestinationIOS.cpp: (WebCore::AudioDestinationIOS::AudioDestinationIOS): m_mediaSession was removed. (WebCore::AudioDestinationIOS::start): Ditto. * platform/audio/ios/AudioDestinationIOS.h: * platform/audio/ios/AudioSessionIOS.mm: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return false if the AVAudioSession could not be activated. (WebCore::AudioSession::setActive): Deleted. * platform/audio/ios/MediaSessionManagerIOS.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Do not update the now playing info if session playback was blocked. * platform/audio/mac/AudioDestinationMac.cpp: (WebCore::AudioDestinationMac::AudioDestinationMac): m_mediaSession was removed. * platform/audio/mac/AudioDestinationMac.h: * platform/audio/mac/AudioSessionMac.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive(). Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/mac/MediaSessionManagerMac.cpp: (MediaSessionManager::updateSessionState): No longer attempt to activate the session, as this is done MediaSessionManager::sessionWillBeginPlayback(). * testing/Internals.cpp: (WebCore::Internals::setMediaSessionRestrictions): Add "InterruptedPlaybackNotPermitted". LayoutTests: * webaudio/audiocontext-state-expected.txt: Added. * webaudio/audiocontext-state-interrupted-expected.txt: Added. * webaudio/audiocontext-state-interrupted.html: Added. * webaudio/audiocontext-state.html: Added. Canonical link: https://commits.webkit.org/161241@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-30 16:15:00 +00:00
testPassed('context.resume() promise resolved');
shouldBe('context.state', '"running"');
debug('Calling context.close()');
context.close().then(closeSucceeded, closeFailed);
}
function closeFailed() {
testFailed('context.close() promise rejected');
finishJSTest();
}
function closeSucceeded(value) {
if (typeof value != 'undefined') {
testFailed('context.closed() promise should not resolve with a value.');
finishJSTest();
return;
}
[iOS] When Web Audio is interrupted by a phone call, it cannot be restarted. https://bugs.webkit.org/show_bug.cgi?id=143190 Reviewed by Darin Adler. Source/WebCore: Tests: webaudio/audiocontext-state-interrupted.html webaudio/audiocontext-state.html Implement the following methods and properties from the Web Audio spec: close(), suspend(), resume(), onstatechange. AudioContext will take more responsibility for tracking state and interruptions (and AudioDestination will give up that responsibility). This means AudioContext must be a MediaSessionClient, and own its own MediaSession. In return, AudioDestinationIOS and AudioDestinationMac relinquish both. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::AudioContext): Set default values in header. (WebCore::AudioContext::uninitialize): Call setState() instead of setting m_state. (WebCore::AudioContext::addReaction): Added. Append the callback to the appropriate vector for the state. (WebCore::AudioContext::setState): Added. Fire events and resolve the appropriate reaction callbacks for the new state. (WebCore::AudioContext::state): Return a string representing the context's state. (WebCore::AudioContext::stop): Close the event queue. (WebCore::AudioContext::startRendering): Call setState(). (WebCore::AudioContext::fireCompletionEvent): Call setState(). (WebCore::AudioContext::suspendContext): Added. Add reaction callback and call suspend() on the destination node. (WebCore::AudioContext::resumeContext): Added. Add reaction callback and call resume() on the destination node. (WebCore::AudioContext::closeContext): Added. Add reaction callback and call close() on the destination node. (WebCore::AudioContext::suspendPlayback): Added. Suspend playback and set state to interrupted. (WebCore::AudioContext::mayResumePlayback): Added. Conditionally resume playback. * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Added. Create and return a new Promise object. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * Modules/webaudio/AudioContext.idl: Add new methods and properties. Extensive organizational changes were made to AudioContext.h to group instance variables together and add C++11 initializers in their declarations: * Modules/webaudio/AudioContext.h: (WebCore::AudioContext::mediaType): Moved from AudioDestinationNode. (WebCore::AudioContext::presentationType): Ditto. (WebCore::AudioContext::canReceiveRemoteControlCommands): Ditto. (WebCore::AudioContext::didReceiveRemoteControlCommand): Ditto. (WebCore::AudioContext::overrideBackgroundPlaybackRestriction): Ditto. Other changes to support the new AudioContext methods: * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): Add empty default virtual method. (WebCore::AudioDestinationNode::suspend): Ditto. (WebCore::AudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::resume): Added. Pass to AudioDestination. (WebCore::DefaultAudioDestinationNode::suspend): Ditto. (WebCore::DefaultAudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.h: * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::resolve): Add an overload for a nullptr resolve value. * dom/EventNames.h: Added 'statechange'. * dom/ScriptExecutionContext.h: (WebCore::ScriptExecutionContext::Task::Task): Add a constructor which takes a void() callback. Modify MediaSession, AudioSession, and MediaSessionManager to support the new interruption behavior. * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::suspendPlayback): Renamed from pausePlayback(). (WebCore::HTMLMediaElement::mayResumePlayback): Renamed from resumePlayback(). * html/HTMLMediaElement.h: * platform/audio/AudioSession.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/AudioSession.h: * platform/audio/MediaSession.cpp: (WebCore::MediaSession::beginInterruption): pausePlayback() was renamed to suspendPlayback(). (WebCore::MediaSession::endInterruption): Always notify the client, telling it whether to resume. (WebCore::MediaSession::clientWillBeginPlayback): Bail early if reentrant. Check the (new) return value of sessionWillBeginPlayback() and remember to resume once the interruption ends. (WebCore::MediaSession::clientWillPausePlayback): Bail early if reentrant. (WebCore::MediaSession::pauseSession): pausePlayback() was renamed to suspendPlayback(). * platform/audio/MediaSession.h: * platform/audio/MediaSessionManager.cpp: (WebCore::MediaSessionManager::sessionWillBeginPlayback): Return false if not allowed to break interruption or if activating the audio session failed. Otherwise, end the interruption. * platform/audio/MediaSessionManager.h: * platform/audio/ios/AudioDestinationIOS.cpp: (WebCore::AudioDestinationIOS::AudioDestinationIOS): m_mediaSession was removed. (WebCore::AudioDestinationIOS::start): Ditto. * platform/audio/ios/AudioDestinationIOS.h: * platform/audio/ios/AudioSessionIOS.mm: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return false if the AVAudioSession could not be activated. (WebCore::AudioSession::setActive): Deleted. * platform/audio/ios/MediaSessionManagerIOS.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Do not update the now playing info if session playback was blocked. * platform/audio/mac/AudioDestinationMac.cpp: (WebCore::AudioDestinationMac::AudioDestinationMac): m_mediaSession was removed. * platform/audio/mac/AudioDestinationMac.h: * platform/audio/mac/AudioSessionMac.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive(). Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/mac/MediaSessionManagerMac.cpp: (MediaSessionManager::updateSessionState): No longer attempt to activate the session, as this is done MediaSessionManager::sessionWillBeginPlayback(). * testing/Internals.cpp: (WebCore::Internals::setMediaSessionRestrictions): Add "InterruptedPlaybackNotPermitted". LayoutTests: * webaudio/audiocontext-state-expected.txt: Added. * webaudio/audiocontext-state-interrupted-expected.txt: Added. * webaudio/audiocontext-state-interrupted.html: Added. * webaudio/audiocontext-state.html: Added. Canonical link: https://commits.webkit.org/161241@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-30 16:15:00 +00:00
testPassed('context.close() promise resolved');
shouldBe('context.state', '"closed"');
debug('Calling context.resume() (should fail)');
context.resume().then(resumeSucceededIncorrectly, resumeFailedCorrectly);
}
function resumeSucceededIncorrectly() {
testFailed('context.resume() promise resolved (should have rejected)');
finishJSTest();
}
AudioContext resume/close/suspend should reject promises with a DOM exception in lieu of throwing exceptions https://bugs.webkit.org/show_bug.cgi?id=145064 Reviewed by Darin Adler. Source/JavaScriptCore: Added default message for TypeError. * runtime/Error.cpp: (JSC::throwTypeError): * runtime/Error.h: Source/WebCore: Rejecting resume/suspend/close promises with InvalidStateError values in case context is offline. Removed unneeded calls to postTask for resolving/rejecting promises. Adding promise rejection of DOM Exception values, 0 being equivalent of no error passed to reject callback. Test: webaudio/audiocontext-promise-throwing.html * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::suspendContext): Rejecting promise in lieu of throwing exception. (WebCore::AudioContext::resumeContext): Ditto. (WebCore::AudioContext::closeContext): Ditto. * Modules/webaudio/AudioContext.h: * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Removing ExceptionCode handling. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * bindings/js/JSDOMBinding.cpp: (WebCore::createDOMException): Splitting DOM exception creation from throwing. (WebCore::setDOMException): Ditto. * bindings/js/JSDOMBinding.h: Adding createDOMException prototype. * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::reject<ExceptionCode>): LayoutTests: Adding test to cover resume/close/suspend rejecting with InvalidStateError. Updating existing test to cover resume and suspend rejection with no error. * webaudio/audiocontext-promise-throwing-expected.txt: Added. * webaudio/audiocontext-promise-throwing.html: Added. * webaudio/audiocontext-state-expected.txt: * webaudio/audiocontext-state.html: Canonical link: https://commits.webkit.org/163228@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@184651 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-05-20 20:20:09 +00:00
function resumeFailedCorrectly(value) {
[iOS] When Web Audio is interrupted by a phone call, it cannot be restarted. https://bugs.webkit.org/show_bug.cgi?id=143190 Reviewed by Darin Adler. Source/WebCore: Tests: webaudio/audiocontext-state-interrupted.html webaudio/audiocontext-state.html Implement the following methods and properties from the Web Audio spec: close(), suspend(), resume(), onstatechange. AudioContext will take more responsibility for tracking state and interruptions (and AudioDestination will give up that responsibility). This means AudioContext must be a MediaSessionClient, and own its own MediaSession. In return, AudioDestinationIOS and AudioDestinationMac relinquish both. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::AudioContext): Set default values in header. (WebCore::AudioContext::uninitialize): Call setState() instead of setting m_state. (WebCore::AudioContext::addReaction): Added. Append the callback to the appropriate vector for the state. (WebCore::AudioContext::setState): Added. Fire events and resolve the appropriate reaction callbacks for the new state. (WebCore::AudioContext::state): Return a string representing the context's state. (WebCore::AudioContext::stop): Close the event queue. (WebCore::AudioContext::startRendering): Call setState(). (WebCore::AudioContext::fireCompletionEvent): Call setState(). (WebCore::AudioContext::suspendContext): Added. Add reaction callback and call suspend() on the destination node. (WebCore::AudioContext::resumeContext): Added. Add reaction callback and call resume() on the destination node. (WebCore::AudioContext::closeContext): Added. Add reaction callback and call close() on the destination node. (WebCore::AudioContext::suspendPlayback): Added. Suspend playback and set state to interrupted. (WebCore::AudioContext::mayResumePlayback): Added. Conditionally resume playback. * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Added. Create and return a new Promise object. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * Modules/webaudio/AudioContext.idl: Add new methods and properties. Extensive organizational changes were made to AudioContext.h to group instance variables together and add C++11 initializers in their declarations: * Modules/webaudio/AudioContext.h: (WebCore::AudioContext::mediaType): Moved from AudioDestinationNode. (WebCore::AudioContext::presentationType): Ditto. (WebCore::AudioContext::canReceiveRemoteControlCommands): Ditto. (WebCore::AudioContext::didReceiveRemoteControlCommand): Ditto. (WebCore::AudioContext::overrideBackgroundPlaybackRestriction): Ditto. Other changes to support the new AudioContext methods: * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): Add empty default virtual method. (WebCore::AudioDestinationNode::suspend): Ditto. (WebCore::AudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::resume): Added. Pass to AudioDestination. (WebCore::DefaultAudioDestinationNode::suspend): Ditto. (WebCore::DefaultAudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.h: * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::resolve): Add an overload for a nullptr resolve value. * dom/EventNames.h: Added 'statechange'. * dom/ScriptExecutionContext.h: (WebCore::ScriptExecutionContext::Task::Task): Add a constructor which takes a void() callback. Modify MediaSession, AudioSession, and MediaSessionManager to support the new interruption behavior. * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::suspendPlayback): Renamed from pausePlayback(). (WebCore::HTMLMediaElement::mayResumePlayback): Renamed from resumePlayback(). * html/HTMLMediaElement.h: * platform/audio/AudioSession.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/AudioSession.h: * platform/audio/MediaSession.cpp: (WebCore::MediaSession::beginInterruption): pausePlayback() was renamed to suspendPlayback(). (WebCore::MediaSession::endInterruption): Always notify the client, telling it whether to resume. (WebCore::MediaSession::clientWillBeginPlayback): Bail early if reentrant. Check the (new) return value of sessionWillBeginPlayback() and remember to resume once the interruption ends. (WebCore::MediaSession::clientWillPausePlayback): Bail early if reentrant. (WebCore::MediaSession::pauseSession): pausePlayback() was renamed to suspendPlayback(). * platform/audio/MediaSession.h: * platform/audio/MediaSessionManager.cpp: (WebCore::MediaSessionManager::sessionWillBeginPlayback): Return false if not allowed to break interruption or if activating the audio session failed. Otherwise, end the interruption. * platform/audio/MediaSessionManager.h: * platform/audio/ios/AudioDestinationIOS.cpp: (WebCore::AudioDestinationIOS::AudioDestinationIOS): m_mediaSession was removed. (WebCore::AudioDestinationIOS::start): Ditto. * platform/audio/ios/AudioDestinationIOS.h: * platform/audio/ios/AudioSessionIOS.mm: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return false if the AVAudioSession could not be activated. (WebCore::AudioSession::setActive): Deleted. * platform/audio/ios/MediaSessionManagerIOS.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Do not update the now playing info if session playback was blocked. * platform/audio/mac/AudioDestinationMac.cpp: (WebCore::AudioDestinationMac::AudioDestinationMac): m_mediaSession was removed. * platform/audio/mac/AudioDestinationMac.h: * platform/audio/mac/AudioSessionMac.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive(). Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/mac/MediaSessionManagerMac.cpp: (MediaSessionManager::updateSessionState): No longer attempt to activate the session, as this is done MediaSessionManager::sessionWillBeginPlayback(). * testing/Internals.cpp: (WebCore::Internals::setMediaSessionRestrictions): Add "InterruptedPlaybackNotPermitted". LayoutTests: * webaudio/audiocontext-state-expected.txt: Added. * webaudio/audiocontext-state-interrupted-expected.txt: Added. * webaudio/audiocontext-state-interrupted.html: Added. * webaudio/audiocontext-state.html: Added. Canonical link: https://commits.webkit.org/161241@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-30 16:15:00 +00:00
testPassed('context.resume() promise rejected (correctly)');
shouldBe('context.state', '"closed"');
debug('Calling context.suspend() (should fail)');
context.suspend().then(suspendSucceededIncorrectly, suspendFailedCorrectly);
}
function suspendSucceededIncorrectly() {
testFailed('context.suspend() promise resolved (should have rejected)');
finishJSTest();
}
function suspendFailedCorrectly() {
AudioContext resume/close/suspend should reject promises with a DOM exception in lieu of throwing exceptions https://bugs.webkit.org/show_bug.cgi?id=145064 Reviewed by Darin Adler. Source/JavaScriptCore: Added default message for TypeError. * runtime/Error.cpp: (JSC::throwTypeError): * runtime/Error.h: Source/WebCore: Rejecting resume/suspend/close promises with InvalidStateError values in case context is offline. Removed unneeded calls to postTask for resolving/rejecting promises. Adding promise rejection of DOM Exception values, 0 being equivalent of no error passed to reject callback. Test: webaudio/audiocontext-promise-throwing.html * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::suspendContext): Rejecting promise in lieu of throwing exception. (WebCore::AudioContext::resumeContext): Ditto. (WebCore::AudioContext::closeContext): Ditto. * Modules/webaudio/AudioContext.h: * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Removing ExceptionCode handling. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * bindings/js/JSDOMBinding.cpp: (WebCore::createDOMException): Splitting DOM exception creation from throwing. (WebCore::setDOMException): Ditto. * bindings/js/JSDOMBinding.h: Adding createDOMException prototype. * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::reject<ExceptionCode>): LayoutTests: Adding test to cover resume/close/suspend rejecting with InvalidStateError. Updating existing test to cover resume and suspend rejection with no error. * webaudio/audiocontext-promise-throwing-expected.txt: Added. * webaudio/audiocontext-promise-throwing.html: Added. * webaudio/audiocontext-state-expected.txt: * webaudio/audiocontext-state.html: Canonical link: https://commits.webkit.org/163228@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@184651 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-05-20 20:20:09 +00:00
testPassed('context.suspend() promise rejected (correctly)');
if (typeof value != 'undefined')
testFailed('No value should be passed to the context.suspend() promise rejected callback');
[iOS] When Web Audio is interrupted by a phone call, it cannot be restarted. https://bugs.webkit.org/show_bug.cgi?id=143190 Reviewed by Darin Adler. Source/WebCore: Tests: webaudio/audiocontext-state-interrupted.html webaudio/audiocontext-state.html Implement the following methods and properties from the Web Audio spec: close(), suspend(), resume(), onstatechange. AudioContext will take more responsibility for tracking state and interruptions (and AudioDestination will give up that responsibility). This means AudioContext must be a MediaSessionClient, and own its own MediaSession. In return, AudioDestinationIOS and AudioDestinationMac relinquish both. * Modules/webaudio/AudioContext.cpp: (WebCore::AudioContext::AudioContext): Set default values in header. (WebCore::AudioContext::uninitialize): Call setState() instead of setting m_state. (WebCore::AudioContext::addReaction): Added. Append the callback to the appropriate vector for the state. (WebCore::AudioContext::setState): Added. Fire events and resolve the appropriate reaction callbacks for the new state. (WebCore::AudioContext::state): Return a string representing the context's state. (WebCore::AudioContext::stop): Close the event queue. (WebCore::AudioContext::startRendering): Call setState(). (WebCore::AudioContext::fireCompletionEvent): Call setState(). (WebCore::AudioContext::suspendContext): Added. Add reaction callback and call suspend() on the destination node. (WebCore::AudioContext::resumeContext): Added. Add reaction callback and call resume() on the destination node. (WebCore::AudioContext::closeContext): Added. Add reaction callback and call close() on the destination node. (WebCore::AudioContext::suspendPlayback): Added. Suspend playback and set state to interrupted. (WebCore::AudioContext::mayResumePlayback): Added. Conditionally resume playback. * bindings/js/JSAudioContextCustom.cpp: (WebCore::JSAudioContext::suspend): Added. Create and return a new Promise object. (WebCore::JSAudioContext::resume): Ditto. (WebCore::JSAudioContext::close): Ditto. * Modules/webaudio/AudioContext.idl: Add new methods and properties. Extensive organizational changes were made to AudioContext.h to group instance variables together and add C++11 initializers in their declarations: * Modules/webaudio/AudioContext.h: (WebCore::AudioContext::mediaType): Moved from AudioDestinationNode. (WebCore::AudioContext::presentationType): Ditto. (WebCore::AudioContext::canReceiveRemoteControlCommands): Ditto. (WebCore::AudioContext::didReceiveRemoteControlCommand): Ditto. (WebCore::AudioContext::overrideBackgroundPlaybackRestriction): Ditto. Other changes to support the new AudioContext methods: * Modules/webaudio/AudioDestinationNode.h: (WebCore::AudioDestinationNode::resume): Add empty default virtual method. (WebCore::AudioDestinationNode::suspend): Ditto. (WebCore::AudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.cpp: (WebCore::DefaultAudioDestinationNode::resume): Added. Pass to AudioDestination. (WebCore::DefaultAudioDestinationNode::suspend): Ditto. (WebCore::DefaultAudioDestinationNode::close): Ditto. * Modules/webaudio/DefaultAudioDestinationNode.h: * bindings/js/JSDOMPromise.h: (WebCore::DeferredWrapper::resolve): Add an overload for a nullptr resolve value. * dom/EventNames.h: Added 'statechange'. * dom/ScriptExecutionContext.h: (WebCore::ScriptExecutionContext::Task::Task): Add a constructor which takes a void() callback. Modify MediaSession, AudioSession, and MediaSessionManager to support the new interruption behavior. * html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::suspendPlayback): Renamed from pausePlayback(). (WebCore::HTMLMediaElement::mayResumePlayback): Renamed from resumePlayback(). * html/HTMLMediaElement.h: * platform/audio/AudioSession.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/AudioSession.h: * platform/audio/MediaSession.cpp: (WebCore::MediaSession::beginInterruption): pausePlayback() was renamed to suspendPlayback(). (WebCore::MediaSession::endInterruption): Always notify the client, telling it whether to resume. (WebCore::MediaSession::clientWillBeginPlayback): Bail early if reentrant. Check the (new) return value of sessionWillBeginPlayback() and remember to resume once the interruption ends. (WebCore::MediaSession::clientWillPausePlayback): Bail early if reentrant. (WebCore::MediaSession::pauseSession): pausePlayback() was renamed to suspendPlayback(). * platform/audio/MediaSession.h: * platform/audio/MediaSessionManager.cpp: (WebCore::MediaSessionManager::sessionWillBeginPlayback): Return false if not allowed to break interruption or if activating the audio session failed. Otherwise, end the interruption. * platform/audio/MediaSessionManager.h: * platform/audio/ios/AudioDestinationIOS.cpp: (WebCore::AudioDestinationIOS::AudioDestinationIOS): m_mediaSession was removed. (WebCore::AudioDestinationIOS::start): Ditto. * platform/audio/ios/AudioDestinationIOS.h: * platform/audio/ios/AudioSessionIOS.mm: (WebCore::AudioSession::tryToSetActive): Renamed from setActive. Return false if the AVAudioSession could not be activated. (WebCore::AudioSession::setActive): Deleted. * platform/audio/ios/MediaSessionManagerIOS.h: * platform/audio/ios/MediaSessionManagerIOS.mm: (WebCore::MediaSessionManageriOS::sessionWillBeginPlayback): Do not update the now playing info if session playback was blocked. * platform/audio/mac/AudioDestinationMac.cpp: (WebCore::AudioDestinationMac::AudioDestinationMac): m_mediaSession was removed. * platform/audio/mac/AudioDestinationMac.h: * platform/audio/mac/AudioSessionMac.cpp: (WebCore::AudioSession::tryToSetActive): Renamed from setActive(). Return true by default. (WebCore::AudioSession::setActive): Deleted. * platform/audio/mac/MediaSessionManagerMac.cpp: (MediaSessionManager::updateSessionState): No longer attempt to activate the session, as this is done MediaSessionManager::sessionWillBeginPlayback(). * testing/Internals.cpp: (WebCore::Internals::setMediaSessionRestrictions): Add "InterruptedPlaybackNotPermitted". LayoutTests: * webaudio/audiocontext-state-expected.txt: Added. * webaudio/audiocontext-state-interrupted-expected.txt: Added. * webaudio/audiocontext-state-interrupted.html: Added. * webaudio/audiocontext-state.html: Added. Canonical link: https://commits.webkit.org/161241@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@182141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-03-30 16:15:00 +00:00
shouldBe('context.state', '"closed"');
finishJSTest();
}
runTest();
</script>
</body>
</html>