WebKit Bugzilla
Attachment 368593 Details for
Bug 197431
: REGRESSION(r244774): Causing assertion failures on debug queues (Requested by ShawnRoberts on #webkit).
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
ROLLOUT of r244774
bug-197431-20190430130603.patch (text/plain), 20.42 KB, created by
WebKit Commit Bot
on 2019-04-30 13:06:04 PDT
(
hide
)
Description:
ROLLOUT of r244774
Filename:
MIME Type:
Creator:
WebKit Commit Bot
Created:
2019-04-30 13:06:04 PDT
Size:
20.42 KB
patch
obsolete
>Subversion Revision: 244794 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 9fefba41f0d1418e2a150043029ce5eb5f395dae..a5a709dd7c6e3313da54339871aa213c331ee30e 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,18 @@ >+2019-04-30 Commit Queue <commit-queue@webkit.org> >+ >+ Unreviewed, rolling out r244774. >+ https://bugs.webkit.org/show_bug.cgi?id=197431 >+ >+ Causing assertion failures on debug queues (Requested by >+ ShawnRoberts on #webkit). >+ >+ Reverted changeset: >+ >+ "Reject/throw when calling AudioContext methods on a stopped >+ AudioContext" >+ https://bugs.webkit.org/show_bug.cgi?id=197391 >+ https://trac.webkit.org/changeset/244774 >+ > 2019-04-30 Alex Christensen <achristensen@webkit.org> > > Add WKContentRuleList ping resource-type >diff --git a/Source/WebCore/Modules/webaudio/AudioContext.cpp b/Source/WebCore/Modules/webaudio/AudioContext.cpp >index 88af339830761ca0da5d1066405d26c4906812c3..9601a668fecd5db008d98324d5712e9999eb5762 100644 >--- a/Source/WebCore/Modules/webaudio/AudioContext.cpp >+++ b/Source/WebCore/Modules/webaudio/AudioContext.cpp >@@ -216,8 +216,6 @@ AudioContext::~AudioContext() > > void AudioContext::lazyInitialize() > { >- ASSERT(!m_isStopScheduled); >- > if (m_isInitialized) > return; > >@@ -432,15 +430,11 @@ void AudioContext::decodeAudioData(Ref<ArrayBuffer>&& audioData, RefPtr<AudioBuf > m_audioDecoder.decodeAsync(WTFMove(audioData), sampleRate(), WTFMove(successCallback), WTFMove(errorCallback)); > } > >-ExceptionOr<Ref<AudioBufferSourceNode>> AudioContext::createBufferSource() >+Ref<AudioBufferSourceNode> AudioContext::createBufferSource() > { > ALWAYS_LOG(LOGIDENTIFIER); >- >+ > ASSERT(isMainThread()); >- >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > Ref<AudioBufferSourceNode> node = AudioBufferSourceNode::create(*this, m_destinationNode->sampleRate()); > >@@ -456,14 +450,13 @@ ExceptionOr<Ref<AudioBufferSourceNode>> AudioContext::createBufferSource() > ExceptionOr<Ref<MediaElementAudioSourceNode>> AudioContext::createMediaElementSource(HTMLMediaElement& mediaElement) > { > ALWAYS_LOG(LOGIDENTIFIER); >- >+ > ASSERT(isMainThread()); >- >- if (m_isStopScheduled || mediaElement.audioSourceNode()) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > >+ if (mediaElement.audioSourceNode()) >+ return Exception { InvalidStateError }; >+ > auto node = MediaElementAudioSourceNode::create(*this, mediaElement); > > mediaElement.setAudioSourceNode(node.ptr()); >@@ -482,9 +475,6 @@ ExceptionOr<Ref<MediaStreamAudioSourceNode>> AudioContext::createMediaStreamSour > > ASSERT(isMainThread()); > >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > auto audioTracks = mediaStream.getAudioTracks(); > if (audioTracks.isEmpty()) > return Exception { InvalidStateError }; >@@ -508,11 +498,8 @@ ExceptionOr<Ref<MediaStreamAudioSourceNode>> AudioContext::createMediaStreamSour > return node; > } > >-ExceptionOr<Ref<MediaStreamAudioDestinationNode>> AudioContext::createMediaStreamDestination() >+Ref<MediaStreamAudioDestinationNode> AudioContext::createMediaStreamDestination() > { >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > // FIXME: Add support for an optional argument which specifies the number of channels. > // FIXME: The default should probably be stereo instead of mono. > return MediaStreamAudioDestinationNode::create(*this, 1); >@@ -525,10 +512,6 @@ ExceptionOr<Ref<ScriptProcessorNode>> AudioContext::createScriptProcessor(size_t > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > > // W3C Editor's Draft 06 June 2017 >@@ -584,87 +567,65 @@ ExceptionOr<Ref<ScriptProcessorNode>> AudioContext::createScriptProcessor(size_t > return node; > } > >-ExceptionOr<Ref<BiquadFilterNode>> AudioContext::createBiquadFilter() >+Ref<BiquadFilterNode> AudioContext::createBiquadFilter() > { > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); >- > return BiquadFilterNode::create(*this, m_destinationNode->sampleRate()); > } > >-ExceptionOr<Ref<WaveShaperNode>> AudioContext::createWaveShaper() >+Ref<WaveShaperNode> AudioContext::createWaveShaper() > { > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > return WaveShaperNode::create(*this); > } > >-ExceptionOr<Ref<PannerNode>> AudioContext::createPanner() >+Ref<PannerNode> AudioContext::createPanner() > { > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > return PannerNode::create(*this, m_destinationNode->sampleRate()); > } > >-ExceptionOr<Ref<ConvolverNode>> AudioContext::createConvolver() >+Ref<ConvolverNode> AudioContext::createConvolver() > { > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > return ConvolverNode::create(*this, m_destinationNode->sampleRate()); > } > >-ExceptionOr<Ref<DynamicsCompressorNode>> AudioContext::createDynamicsCompressor() >+Ref<DynamicsCompressorNode> AudioContext::createDynamicsCompressor() > { > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > return DynamicsCompressorNode::create(*this, m_destinationNode->sampleRate()); > } > >-ExceptionOr<Ref<AnalyserNode>> AudioContext::createAnalyser() >+Ref<AnalyserNode> AudioContext::createAnalyser() > { > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > return AnalyserNode::create(*this, m_destinationNode->sampleRate()); > } > >-ExceptionOr<Ref<GainNode>> AudioContext::createGain() >+Ref<GainNode> AudioContext::createGain() > { > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > return GainNode::create(*this, m_destinationNode->sampleRate()); > } >@@ -674,9 +635,6 @@ ExceptionOr<Ref<DelayNode>> AudioContext::createDelay(double maxDelayTime) > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > return DelayNode::create(*this, m_destinationNode->sampleRate(), maxDelayTime); > } >@@ -686,9 +644,6 @@ ExceptionOr<Ref<ChannelSplitterNode>> AudioContext::createChannelSplitter(size_t > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > auto node = ChannelSplitterNode::create(*this, m_destinationNode->sampleRate(), numberOfOutputs); > if (!node) >@@ -701,9 +656,6 @@ ExceptionOr<Ref<ChannelMergerNode>> AudioContext::createChannelMerger(size_t num > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > auto node = ChannelMergerNode::create(*this, m_destinationNode->sampleRate(), numberOfInputs); > if (!node) >@@ -711,14 +663,11 @@ ExceptionOr<Ref<ChannelMergerNode>> AudioContext::createChannelMerger(size_t num > return node.releaseNonNull(); > } > >-ExceptionOr<Ref<OscillatorNode>> AudioContext::createOscillator() >+Ref<OscillatorNode> AudioContext::createOscillator() > { > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > lazyInitialize(); > > Ref<OscillatorNode> node = OscillatorNode::create(*this, m_destinationNode->sampleRate()); >@@ -735,9 +684,6 @@ ExceptionOr<Ref<PeriodicWave>> AudioContext::createPeriodicWave(Float32Array& re > ALWAYS_LOG(LOGIDENTIFIER); > > ASSERT(isMainThread()); >- if (m_isStopScheduled) >- return Exception { InvalidStateError }; >- > if (real.length() != imaginary.length() || (real.length() > MaxPeriodicWaveLength) || !real.length()) > return Exception { IndexSizeError }; > lazyInitialize(); >@@ -1132,7 +1078,7 @@ bool AudioContext::willPausePlayback() > void AudioContext::startRendering() > { > ALWAYS_LOG(LOGIDENTIFIER); >- if (m_isStopScheduled || !willBeginPlayback()) >+ if (!willBeginPlayback()) > return; > > destination()->startRendering(); >@@ -1204,7 +1150,7 @@ void AudioContext::decrementActiveSourceCount() > > void AudioContext::suspend(DOMPromiseDeferred<void>&& promise) > { >- if (isOfflineContext() || m_isStopScheduled) { >+ if (isOfflineContext()) { > promise.reject(InvalidStateError); > return; > } >@@ -1233,7 +1179,7 @@ void AudioContext::suspend(DOMPromiseDeferred<void>&& promise) > > void AudioContext::resume(DOMPromiseDeferred<void>&& promise) > { >- if (isOfflineContext() || m_isStopScheduled) { >+ if (isOfflineContext()) { > promise.reject(InvalidStateError); > return; > } >@@ -1262,7 +1208,7 @@ void AudioContext::resume(DOMPromiseDeferred<void>&& promise) > > void AudioContext::close(DOMPromiseDeferred<void>&& promise) > { >- if (isOfflineContext() || m_isStopScheduled) { >+ if (isOfflineContext()) { > promise.reject(InvalidStateError); > return; > } >diff --git a/Source/WebCore/Modules/webaudio/AudioContext.h b/Source/WebCore/Modules/webaudio/AudioContext.h >index 3705c4953eac66052d6bd310fbe4fa8038ae1bc5..86c57c3df6aa670019d0addc1345705ae4f2b095 100644 >--- a/Source/WebCore/Modules/webaudio/AudioContext.h >+++ b/Source/WebCore/Modules/webaudio/AudioContext.h >@@ -134,26 +134,26 @@ public: > bool wouldTaintOrigin(const URL&) const; > > // The AudioNode create methods are called on the main thread (from JavaScript). >- ExceptionOr<Ref<AudioBufferSourceNode>> createBufferSource(); >+ Ref<AudioBufferSourceNode> createBufferSource(); > #if ENABLE(VIDEO) > ExceptionOr<Ref<MediaElementAudioSourceNode>> createMediaElementSource(HTMLMediaElement&); > #endif > #if ENABLE(MEDIA_STREAM) > ExceptionOr<Ref<MediaStreamAudioSourceNode>> createMediaStreamSource(MediaStream&); >- ExceptionOr<Ref<MediaStreamAudioDestinationNode>> createMediaStreamDestination(); >+ Ref<MediaStreamAudioDestinationNode> createMediaStreamDestination(); > #endif >- ExceptionOr<Ref<GainNode>> createGain(); >- ExceptionOr<Ref<BiquadFilterNode>> createBiquadFilter(); >- ExceptionOr<Ref<WaveShaperNode>> createWaveShaper(); >+ Ref<GainNode> createGain(); >+ Ref<BiquadFilterNode> createBiquadFilter(); >+ Ref<WaveShaperNode> createWaveShaper(); > ExceptionOr<Ref<DelayNode>> createDelay(double maxDelayTime); >- ExceptionOr<Ref<PannerNode>> createPanner(); >- ExceptionOr<Ref<ConvolverNode>> createConvolver(); >- ExceptionOr<Ref<DynamicsCompressorNode>> createDynamicsCompressor(); >- ExceptionOr<Ref<AnalyserNode>> createAnalyser(); >+ Ref<PannerNode> createPanner(); >+ Ref<ConvolverNode> createConvolver(); >+ Ref<DynamicsCompressorNode> createDynamicsCompressor(); >+ Ref<AnalyserNode> createAnalyser(); > ExceptionOr<Ref<ScriptProcessorNode>> createScriptProcessor(size_t bufferSize, size_t numberOfInputChannels, size_t numberOfOutputChannels); > ExceptionOr<Ref<ChannelSplitterNode>> createChannelSplitter(size_t numberOfOutputs); > ExceptionOr<Ref<ChannelMergerNode>> createChannelMerger(size_t numberOfInputs); >- ExceptionOr<Ref<OscillatorNode>> createOscillator(); >+ Ref<OscillatorNode> createOscillator(); > ExceptionOr<Ref<PeriodicWave>> createPeriodicWave(Float32Array& real, Float32Array& imaginary); > > // When a source node has no more processing to do (has finished playing), then it tells the context to dereference it. >diff --git a/Source/WebCore/Modules/webaudio/AudioContext.idl b/Source/WebCore/Modules/webaudio/AudioContext.idl >index bf7a4ff3565ddee62c2136549ade1c0dbc13cef1..a114202b01f8b3378ff66be73a9f0b963e3527ac 100644 >--- a/Source/WebCore/Modules/webaudio/AudioContext.idl >+++ b/Source/WebCore/Modules/webaudio/AudioContext.idl >@@ -69,24 +69,24 @@ enum AudioContextState { > void decodeAudioData(ArrayBuffer audioData, AudioBufferCallback? successCallback, optional AudioBufferCallback? errorCallback); > > // Sources >- [MayThrowException] AudioBufferSourceNode createBufferSource(); >+ AudioBufferSourceNode createBufferSource(); > > [Conditional=VIDEO, MayThrowException] MediaElementAudioSourceNode createMediaElementSource(HTMLMediaElement mediaElement); > > [Conditional=MEDIA_STREAM, MayThrowException] MediaStreamAudioSourceNode createMediaStreamSource(MediaStream mediaStream); >- [Conditional=MEDIA_STREAM, MayThrowException] MediaStreamAudioDestinationNode createMediaStreamDestination(); >+ [Conditional=MEDIA_STREAM] MediaStreamAudioDestinationNode createMediaStreamDestination(); > > // Processing nodes >- [MayThrowException] GainNode createGain(); >+ GainNode createGain(); > [MayThrowException] DelayNode createDelay(optional unrestricted double maxDelayTime = 1); >- [MayThrowException] BiquadFilterNode createBiquadFilter(); >- [MayThrowException] WaveShaperNode createWaveShaper(); >- [MayThrowException] PannerNode createPanner(); >- [MayThrowException] ConvolverNode createConvolver(); >- [MayThrowException] DynamicsCompressorNode createDynamicsCompressor(); >- [MayThrowException] AnalyserNode createAnalyser(); >+ BiquadFilterNode createBiquadFilter(); >+ WaveShaperNode createWaveShaper(); >+ PannerNode createPanner(); >+ ConvolverNode createConvolver(); >+ DynamicsCompressorNode createDynamicsCompressor(); >+ AnalyserNode createAnalyser(); > [MayThrowException] ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0, optional unsigned long numberOfInputChannels = 2, optional unsigned long numberOfOutputChannels = 2); >- [MayThrowException] OscillatorNode createOscillator(); >+ OscillatorNode createOscillator(); > [MayThrowException] PeriodicWave createPeriodicWave(Float32Array real, Float32Array imag); > > // Channel splitting and merging >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index e62e24af220a81b4917bcb4591e180b6fc394ab5..a79372dd9b32aaf1adc394aa153a64e7a032cc0b 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,18 @@ >+2019-04-30 Commit Queue <commit-queue@webkit.org> >+ >+ Unreviewed, rolling out r244774. >+ https://bugs.webkit.org/show_bug.cgi?id=197431 >+ >+ Causing assertion failures on debug queues (Requested by >+ ShawnRoberts on #webkit). >+ >+ Reverted changeset: >+ >+ "Reject/throw when calling AudioContext methods on a stopped >+ AudioContext" >+ https://bugs.webkit.org/show_bug.cgi?id=197391 >+ https://trac.webkit.org/changeset/244774 >+ > 2019-04-30 Alex Christensen <achristensen@webkit.org> > > Add WKContentRuleList ping resource-type >diff --git a/LayoutTests/http/wpt/webaudio/audiocontext-stopped-expected.txt b/LayoutTests/http/wpt/webaudio/audiocontext-stopped-expected.txt >deleted file mode 100644 >index 2cffd4593172b283105af3e512afeadfe9185c7f..0000000000000000000000000000000000000000 >--- a/LayoutTests/http/wpt/webaudio/audiocontext-stopped-expected.txt >+++ /dev/null >@@ -1,21 +0,0 @@ >- >- >-PASS Load test iframe >-PASS createBufferSource >-PASS createMediaElementSource >-PASS createMediaStreamDestination >-PASS createGain >-PASS createDelay >-PASS createBiquadFilter >-PASS createWaveShapper >-PASS createPanner >-PASS createConvolver >-PASS createDynamicsCompressor >-PASS createAnalyser >-PASS createScriptProcessor >-PASS createOscillator >-PASS createPeriodicWave >-PASS suspend >-PASS resume >-PASS close >- >diff --git a/LayoutTests/http/wpt/webaudio/audiocontext-stopped.html b/LayoutTests/http/wpt/webaudio/audiocontext-stopped.html >deleted file mode 100644 >index 09670899b3b6a712f0714d03f3f4f2e5867c9d91..0000000000000000000000000000000000000000 >--- a/LayoutTests/http/wpt/webaudio/audiocontext-stopped.html >+++ /dev/null >@@ -1,100 +0,0 @@ >-<!DOCTYPE html> >-<html> >-<head> >-<script src="/resources/testharness.js"></script> >-<script src="/resources/testharnessreport.js"></script> >-</head> >-<body> >-<video id="video"></video> >-<script> >-function with_iframe(url) { >- return new Promise(function(resolve) { >- var frame = document.createElement('iframe'); >- frame.className = 'test-iframe'; >- frame.src = url; >- frame.onload = function() { resolve(frame); }; >- document.body.appendChild(frame); >- }); >-} >- >-var context; >-promise_test(async () => { >- const iframe = await with_iframe("resources/audiocontext-stopped-iframe.html"); >- context = iframe.contentWindow.audioContext; >- iframe.remove(); >- >- runTests(); >-}, "Load test iframe"); >- >-function runTests() >-{ >- test(() => { >- assert_throws('InvalidStateError', () => context.createBufferSource()); >- }, "createBufferSource"); >- test(() => { >- assert_throws('InvalidStateError', () => context.createMediaElementSource(video)); >- }, "createMediaElementSource"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createMediaStreamDestination()); >- }, "createMediaStreamDestination"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createGain()); >- }, "createGain"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createDelay()); >- }, "createDelay"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createBiquadFilter()); >- }, "createBiquadFilter"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createWaveShaper()); >- }, "createWaveShapper"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createPanner()); >- }, "createPanner"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createConvolver()); >- }, "createConvolver"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createDynamicsCompressor()); >- }, "createDynamicsCompressor"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createAnalyser()); >- }, "createAnalyser"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createScriptProcessor()); >- }, "createScriptProcessor"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createOscillator()); >- }, "createOscillator"); >- >- test(() => { >- assert_throws('InvalidStateError', () => context.createPeriodicWave(new Float32Array(1), new Float32Array(1))); >- }, "createPeriodicWave"); >- >- promise_test((test) => { >- return promise_rejects(test, 'InvalidStateError', context.suspend()); >- }, "suspend"); >- >- promise_test((test) => { >- return promise_rejects(test, 'InvalidStateError', context.resume()); >- }, "resume"); >- >- promise_test((test) => { >- return promise_rejects(test, 'InvalidStateError', context.close()); >- }, "close"); >-} >-</script> >-</body> >-</html> >diff --git a/LayoutTests/http/wpt/webaudio/resources/audiocontext-stopped-iframe.html b/LayoutTests/http/wpt/webaudio/resources/audiocontext-stopped-iframe.html >deleted file mode 100644 >index 8b1dca0a631aef958b74ad11301dbec6ab4de6bc..0000000000000000000000000000000000000000 >--- a/LayoutTests/http/wpt/webaudio/resources/audiocontext-stopped-iframe.html >+++ /dev/null >@@ -1,3 +0,0 @@ >-<script> >-window.audioContext = new webkitAudioContext(); >-</script> >diff --git a/LayoutTests/platform/win/TestExpectations b/LayoutTests/platform/win/TestExpectations >index ac87428f0ff381c4f705aa5f37abbf2e45e392b7..450805b64508e9db49857ef927564547201acbad 100644 >--- a/LayoutTests/platform/win/TestExpectations >+++ b/LayoutTests/platform/win/TestExpectations >@@ -494,7 +494,6 @@ webkit.org/b/61540 http/tests/security/isolatedWorld/cross-origin-xhr.html [ Ski > > # TODO For now, Web Audio tests are disabled > webkit.org/b/86914 webaudio/ [ Skip ] >-webkit.org/b/86914 http/wpt/webaudio/ [ Skip ] > webkit.org/b/86914 fast/history/page-cache-closed-audiocontext.html [ Skip ] > webkit.org/b/86914 fast/history/page-cache-running-audiocontext.html [ Skip ] > webkit.org/b/86914 fast/history/page-cache-suspended-audiocontext.html [ Skip ]
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 197431
: 368593