Changeset 268893 in webkit
- Timestamp:
- Oct 22, 2020 2:56:24 PM (21 months ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 edited
-
ChangeLog (modified) (1 diff)
-
Modules/webaudio/AudioContext.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r268889 r268893 1 2020-10-22 Chris Dumez <cdumez@apple.com> 2 3 Web Audio continues to play when navigating off the web page via an iframe 4 https://bugs.webkit.org/show_bug.cgi?id=218078 5 6 Reviewed by Eric Carlson. 7 8 The page was suspending playback when clicking the link and then resuming playback in the pagehide 9 event handler. The issue is that the AudioContext's state gets updated asynchronously when the 10 page suspends or resume rendering, as per specification. When entering the back/forward cache, 11 AudioContext::suspend() would be called but would do nothing because the state was "suspended", 12 despite the script having just called "resume()". To address the issue, AudioContext::suspend() 13 now early returns only if the context is closed or based on the m_wasSuspendedByScript flag 14 when gets updated synchronously when the script calls suspend() / resume(). Similarly, 15 AudioContext::resume() checks those same flags now. 16 17 No new tests, this impacts audio rendering on speakers but is not web-observable. 18 19 * Modules/webaudio/AudioContext.cpp: 20 (WebCore::AudioContext::resumeRendering): 21 Check if the MediaSession is interrupted before asynchronously setting the AudioContext's state 22 to "running". This is important because the state gets updated asynchronously but the MediaSession 23 can be interrupted synchronously when AudioContext::suspend() gets called, which would have set 24 the AudioContext's state to "interrupted". We don't want to incorrectly change the state from 25 "interrupted" to "running" in this case. Note that AudioContext::suspendRendering() already does 26 the same thing. 27 28 (WebCore::AudioContext::suspend): 29 (WebCore::AudioContext::resume): 30 Only early return if the AudioContext is closed or if the m_wasSuspendedByScript flag is set. The 31 m_wasSuspendedByScript gets updated synchronously when suspendRendering() / resumeRendering() get 32 called, unlike the AudioContext's state which gets updated asynchronously. 33 34 (WebCore::AudioContext::suspendPlayback): 35 Stop early returning if the state is "suspended". This was wrong since the state gets updated 36 asynchronously. 37 1 38 2020-10-22 Martin Robinson <mrobinson@igalia.com> 2 39 -
trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp
r268812 r268893 249 249 250 250 destinationNode()->resume([this, protectedThis = makeRef(*this)] { 251 setState(State::Running); 251 // Since we update the state asynchronously, we may have been interrupted after the 252 // call to resume() and before this lambda runs. In this case, we don't want to 253 // reset the state to running. 254 bool interrupted = m_mediaSession->state() == PlatformMediaSession::Interrupted; 255 setState(interrupted ? State::Interrupted : State::Running); 252 256 }); 253 257 } … … 403 407 void AudioContext::suspend(ReasonForSuspension) 404 408 { 405 if (state() == State::Running) { 406 m_mediaSession->beginInterruption(PlatformMediaSession::PlaybackSuspended); 407 document()->updateIsPlayingMedia(); 408 } 409 if (isClosed() || m_wasSuspendedByScript) 410 return; 411 412 m_mediaSession->beginInterruption(PlatformMediaSession::PlaybackSuspended); 413 document()->updateIsPlayingMedia(); 409 414 } 410 415 411 416 void AudioContext::resume() 412 417 { 413 if (state() == State::Interrupted) { 414 m_mediaSession->endInterruption(PlatformMediaSession::MayResumePlaying); 415 document()->updateIsPlayingMedia(); 416 } 418 if (isClosed() || m_wasSuspendedByScript) 419 return; 420 421 m_mediaSession->endInterruption(PlatformMediaSession::MayResumePlaying); 422 document()->updateIsPlayingMedia(); 417 423 } 418 424 … … 421 427 if (!destinationNode() || state() == State::Closed) 422 428 return; 423 424 if (state() == State::Suspended) {425 if (m_mediaSession->state() == PlatformMediaSession::Interrupted)426 setState(State::Interrupted);427 return;428 }429 429 430 430 lazyInitialize();
Note: See TracChangeset
for help on using the changeset viewer.