Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: ee87be3a43275f2c14fbe8248938c6fce3d31651
https://github.com/WebKit/WebKit/commit/ee87be3a43275f2c14fbe8248938c6fce3d31651
Author: Eric Carlson <[email protected]>
Date: 2026-07-23 (Thu, 23 Jul 2026)
Changed paths:
A
LayoutTests/fast/mediastream/audio-session-active-when-capture-starts-and-stops-expected.txt
A
LayoutTests/fast/mediastream/audio-session-active-when-capture-starts-and-stops.html
A
LayoutTests/fast/mediastream/audio-session-stays-active-during-capture-expected.txt
A
LayoutTests/fast/mediastream/audio-session-stays-active-during-capture.html
A
LayoutTests/fast/mediastream/audio-session-stays-active-when-removing-session-during-capture-expected.txt
A
LayoutTests/fast/mediastream/audio-session-stays-active-when-removing-session-during-capture.html
M
LayoutTests/media/picture-in-picture/video-playback-system-interruption-and-resume-expected.txt
M
LayoutTests/media/picture-in-picture/video-playback-system-interruption-and-resume.html
M LayoutTests/media/video-currenttime-monotonic.html
M LayoutTests/platform/glib/TestExpectations
M LayoutTests/platform/mac-site-isolation/TestExpectations
M LayoutTests/platform/mac-wk2/TestExpectations
A
LayoutTests/platform/mac/media/audio-session-stays-active-when-muted-expected.txt
A LayoutTests/platform/mac/media/audio-session-stays-active-when-muted.html
M Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
M Source/WebCore/Modules/audiosession/DOMAudioSession.cpp
M Source/WebCore/Modules/mediasession/MediaSession.cpp
M Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp
M Source/WebCore/Modules/mediastream/UserMediaRequest.cpp
M Source/WebCore/Modules/webaudio/AudioContext.cpp
M Source/WebCore/Modules/webaudio/BaseAudioContext.h
M Source/WebCore/html/HTMLMediaElement.cpp
M Source/WebCore/html/HTMLMediaElement.h
M Source/WebCore/html/MediaElementSession.h
M Source/WebCore/platform/LogMessages.in
M Source/WebCore/platform/audio/AudioSession.cpp
M Source/WebCore/platform/audio/AudioSession.h
M Source/WebCore/platform/audio/MediaSessionManagerInterface.cpp
M Source/WebCore/platform/audio/MediaSessionManagerInterface.h
M Source/WebCore/platform/audio/PlatformMediaSession.cpp
M Source/WebCore/platform/audio/cocoa/AudioSessionCocoa.h
M Source/WebCore/platform/audio/cocoa/AudioSessionCocoa.mm
M Source/WebCore/platform/mediastream/cocoa/BaseAudioCaptureUnit.cpp
M Source/WebCore/testing/Internals.cpp
M Source/WebCore/testing/Internals.h
M Source/WebCore/testing/Internals.idl
M Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.cpp
M Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.h
M Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.messages.in
M Source/WebKit/GPUProcess/media/RemoteAudioSessionProxyManager.cpp
M Source/WebKit/GPUProcess/media/RemoteAudioSessionProxyManager.h
M Source/WebKit/GPUProcess/webrtc/UserMediaCaptureManagerProxy.cpp
M Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.cpp
M Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.h
M Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.cpp
M Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.h
M Source/WebKit/WebProcess/Media/RemoteMediaSessionManager.cpp
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/MediaBufferingPolicy.mm
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/MediaSession.mm
Log Message:
-----------
[Site isolation] Re-land AudioSession asynchronous activation
https://bugs.webkit.org/show_bug.cgi?id=319813
rdar://182709192
Reviewed by Jer Noble.
This re-lands 316303@main and its microphone-capture follow-up 316394@main,
which were rolled out together in 316719@main after a cluster of regressions.
Those regressions are addressed here:
- Permanent loss of audio after mute/unmute (rdar://181517699), which was caused
by the maybeActivateAudioSession()'s "not required" branch no longer tearing
down the audio session. Restore the pre-async activate-or-no-op contract.
Pages whose audible content lives in Autoplaying rather than Playing
(e.g. YouTube audio elements) no longer lose their session. Added a new
regression test platform/mac/media/audio-session-stays-active-when-muted.html
that asserts that muting the only playing element does not deactivate the
session
(while process suspension still does); it fails without this fix.
- The platform/mac/media/audio-session-deactivated-when-suspended.html flake
(webkit.org/b/318452): sessionCanProduceAudioChanged() now activates
synchronously, and sessionWillBeginPlayback() completes the playback admission
before the activeAudioSessionRequired() deactivation check.
- AudioContext::willBeginPlayback() again calls setActive(true) (which sends
AddMediaSession) before clientWillBeginPlayback() (which sends
MediaSessionWillBeginPlayback), matching HTMLMediaElement::playInternal(), so
a
site-isolated AudioContext registers its session with the UI process before
its
playback request arrives (webkit.org/b/318459).
The MediaBufferingPolicy flake (webkit.org/b/318485) is not yet root-caused as
it
has never been reproduced locally so the test remains gardened. This change adds
diagnostics so a failure will be captured the next time it flakes on the bots.
`AudioSession::tryToSetActive(bool)` now returns `Ref<SetActivePromise>` instead
of a synchronous `bool`. This is a prerequisite for moving the media session
manager completely out of the WebContent process under site isolation: the
existing sync IPC from WebContent to the GPU process that confirmed audio
session
activation cannot be extended to an additional UI-process hop without making the
entire chain async.
The `TryToSetActive` IPC message is now reply-with-promise rather than
synchronous, so `RemoteAudioSession::tryToSetActiveInternal()` no longer blocks
the WebContent main thread on a GPU round-trip.
`MediaSessionManagerInterface::sessionWillBeginPlayback()` is restructured: when
activation is already in place it takes the fast synchronous path and fires its
completion handler inline; when activation is required it chains the completion
handler off the activation promise via `whenSettled()`.
`MediaSessionManagerInterface::maybeActivateAudioSession()` returns its own
promise, and gives each concurrent caller its own `GenericPromise::Producer`
(held in `m_activationWaiters`) so multiple callers can chain off a single
in-flight activation. The producers are settled together when the underlying
`tryToSetActive(true)` completes.
`RemoteAudioSession::tryToSetActiveInternal()` keeps at most one IPC in flight
at
a time using a FIFO chain (`m_pendingActivationChain`). Consecutive same-state
requests coalesce against the tail of the chain into a single IPC;
alternating-state requests append a new entry that is dispatched when the
previous reply arrives. Serializing at this layer preserves request ordering
independently of how `AudioSessionCocoa::tryToSetActiveInternal()` is
implemented, which matters once activation there becomes truly non-blocking.
`AudioSessionCocoa::tryToSetActiveInternal()` activation still uses
`dispatchSync`
internally; only deactivation is fully async at this layer for now. The promise
infrastructure is in place to make activation non-blocking in a follow-up
change.
The microphone-capture follow-up (316394@main) keeps the WebProcess AudioSession
active for the duration of capture by centralizing the "is capture or another
session keeping the AudioSession alive?" check inside
maybeDeactivateAudioSession(),
so process suspension, removal of the last PlatformMediaSession, and
capture-state changes are all consistently guarded; UserMediaRequest::allow() no
longer activates the AudioSession directly, keeping m_becameActive in sync.
Add an AsyncAudioSessionActivationEnabled runtime preference (default true).
When
this preference is false it makes the IPC to the GPU process synchronous, to
make
it easier to test whether regressions are caused by the change to async IPC or
by
the change to using NativePromise in the AudioSession activation code path.
Fix a pre-existing clearInterval(checkCurrentTime) bug in
video-currenttime-monotonic.html that caused spurious "time went backward"
failures when the interval kept running across video-end boundaries.
Tests: fast/mediastream/audio-session-active-when-capture-starts-and-stops.html
fast/mediastream/audio-session-stays-active-during-capture.html
fast/mediastream/audio-session-stays-active-when-removing-session-during-capture.html
platform/mac/media/audio-session-stays-active-when-muted.html
Tools/TestWebKitAPI/Tests/WebKit/WKWebView/MediaBufferingPolicy.mm
Tools/TestWebKitAPI/Tests/WebKit/WKWebView/MediaSession.mm
*
LayoutTests/fast/mediastream/audio-session-active-when-capture-starts-and-stops-expected.txt:
Added.
*
LayoutTests/fast/mediastream/audio-session-active-when-capture-starts-and-stops.html:
Added.
*
LayoutTests/fast/mediastream/audio-session-stays-active-during-capture-expected.txt:
Added.
* LayoutTests/fast/mediastream/audio-session-stays-active-during-capture.html:
Added.
*
LayoutTests/fast/mediastream/audio-session-stays-active-when-removing-session-during-capture-expected.txt:
Added.
*
LayoutTests/fast/mediastream/audio-session-stays-active-when-removing-session-during-capture.html:
Added.
*
LayoutTests/media/picture-in-picture/video-playback-system-interruption-and-resume-expected.txt:
*
LayoutTests/media/picture-in-picture/video-playback-system-interruption-and-resume.html:
* LayoutTests/media/video-currenttime-monotonic.html:
* LayoutTests/platform/glib/TestExpectations:
* LayoutTests/platform/mac-site-isolation/TestExpectations:
* LayoutTests/platform/mac-wk2/TestExpectations:
*
LayoutTests/platform/mac/media/audio-session-stays-active-when-muted-expected.txt:
Added.
* LayoutTests/platform/mac/media/audio-session-stays-active-when-muted.html:
Added.
* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml:
* Source/WebCore/Modules/audiosession/DOMAudioSession.cpp:
(WebCore::DOMAudioSession::scheduleStateChangeEvent):
* Source/WebCore/Modules/mediasession/MediaSession.cpp:
(WebCore::MediaSession::updateCaptureState):
* Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp:
(WebCore::MediaStreamTrack::trackMutedChanged):
(WebCore::MediaStreamTrack::isCapturingAudio const):
(WebCore::MediaStreamTrack::wantsToCaptureAudio const):
* Source/WebCore/Modules/mediastream/UserMediaRequest.cpp:
(WebCore::UserMediaRequest::allow):
* Source/WebCore/Modules/webaudio/AudioContext.cpp:
(WebCore::AudioContext::close):
(WebCore::AudioContext::suspendRendering):
(WebCore::AudioContext::resumeRendering):
(WebCore::AudioContext::startRendering):
(WebCore::AudioContext::lazyInitialize):
(WebCore::AudioContext::mayResumePlayback):
(WebCore::AudioContext::suspendPlayback):
* Source/WebCore/Modules/webaudio/BaseAudioContext.h:
(WebCore::BaseAudioContext::isRunning const):
* Source/WebCore/html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::load):
(WebCore::HTMLMediaElement::prepareForLoad):
(WebCore::HTMLMediaElement::selectMediaResource):
(WebCore::HTMLMediaElement::completePlayInternal):
(WebCore::HTMLMediaElement::playInternal):
(WebCore::HTMLMediaElement::pauseInternal):
* Source/WebCore/html/HTMLMediaElement.h:
* Source/WebCore/html/MediaElementSession.h:
* Source/WebCore/platform/LogMessages.in:
* Source/WebCore/platform/audio/AudioSession.cpp:
(WebCore::AudioSession::tryToSetActive):
(WebCore::AudioSession::tryToSetActiveInternal):
* Source/WebCore/platform/audio/AudioSession.h:
* Source/WebCore/platform/audio/MediaSessionManagerInterface.cpp:
(WebCore::MediaSessionManagerInterface::processWillSuspend):
(WebCore::MediaSessionManagerInterface::sessionWillBeginPlayback):
(WebCore::MediaSessionManagerInterface::enforceConcurrentPlaybackRestriction):
(WebCore::MediaSessionManagerInterface::sessionCanProduceAudioChanged):
(WebCore::MediaSessionManagerInterface::audioCaptureSourceStateChanged):
(WebCore::MediaSessionManagerInterface::removeSession):
(WebCore::MediaSessionManagerInterface::maybeDeactivateAudioSession):
(WebCore::MediaSessionManagerInterface::maybeActivateAudioSession):
* Source/WebCore/platform/audio/MediaSessionManagerInterface.h:
* Source/WebCore/platform/audio/PlatformMediaSession.cpp:
(WebCore::PlatformMediaSession::clientWillBeginPlayback):
(WebCore::PlatformMediaSession::processClientWillPausePlayback):
(WebCore::PlatformMediaSession::canProduceAudioChanged):
* Source/WebCore/platform/audio/cocoa/AudioSessionCocoa.h:
* Source/WebCore/platform/audio/cocoa/AudioSessionCocoa.mm:
(WebCore::AudioSessionCocoa::tryToSetActiveInternal):
* Source/WebCore/platform/mediastream/cocoa/BaseAudioCaptureUnit.cpp:
(WebCore::BaseAudioCaptureUnit::continueStartProducingData):
* Source/WebCore/testing/Internals.cpp:
(WebCore::Internals::resetToConsistentState):
(WebCore::bufferingPolicyToString):
(WebCore::Internals::elementBufferingPolicy):
(WebCore::Internals::elementPreferredBufferingPolicy):
* Source/WebCore/testing/Internals.h:
* Source/WebCore/testing/Internals.idl:
* Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.cpp:
(WebKit::RemoteAudioSessionProxy::tryToSetActive):
(WebKit::RemoteAudioSessionProxy::tryToSetActiveSync):
* Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.h:
* Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.messages.in:
* Source/WebKit/GPUProcess/media/RemoteAudioSessionProxyManager.cpp:
(WebKit::RemoteAudioSessionProxyManager::tryToSetActiveForProcess):
* Source/WebKit/GPUProcess/media/RemoteAudioSessionProxyManager.h:
* Source/WebKit/GPUProcess/webrtc/UserMediaCaptureManagerProxy.cpp:
* Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.cpp:
(WebKit::RemoteMediaSessionManagerProxy::tryToSetActiveInternal):
* Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.h:
* Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.cpp:
(WebKit::RemoteAudioSession::tryToSetActiveInternal):
(WebKit::RemoteAudioSession::sendNextActivationIPC):
* Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.h:
* Source/WebKit/WebProcess/Media/RemoteMediaSessionManager.cpp:
(WebKit::RemoteMediaSessionManager::tryToSetAudioSessionActive):
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/MediaBufferingPolicy.mm:
(waitUntilBufferingPolicyIsEqualTo):
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/MediaSession.mm:
(TestWebKitAPI::MediaSessionTest::loadPageAndBecomeNowPlaying):
Canonical link: https://commits.webkit.org/317782@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications