Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: eca8e2cf2518a805495f9ce2ad0fce1c57b75eb1
https://github.com/WebKit/WebKit/commit/eca8e2cf2518a805495f9ce2ad0fce1c57b75eb1
Author: Jean-Yves Avenard <[email protected]>
Date: 2026-08-15 (Sat, 15 Aug 2026)
Changed paths:
M
LayoutTests/fast/harness/internals-object-property-access-on-window-without-frame-crash.html
A
LayoutTests/http/tests/site-isolation/audio-session-category-capture-and-playback-expected.txt
A
LayoutTests/http/tests/site-isolation/audio-session-category-capture-and-playback.html
A
LayoutTests/http/tests/site-isolation/audio-session-category-override-after-playback-expected.txt
A
LayoutTests/http/tests/site-isolation/audio-session-category-override-after-playback.html
A
LayoutTests/http/tests/site-isolation/audio-session-category-override-and-playback-expected.txt
A
LayoutTests/http/tests/site-isolation/audio-session-category-override-and-playback.html
A
LayoutTests/http/tests/site-isolation/audio-session-category-override-does-not-affect-another-page-expected.txt
A
LayoutTests/http/tests/site-isolation/audio-session-category-override-does-not-affect-another-page.html
A
LayoutTests/http/tests/site-isolation/resources/audio-session-capture-frame.html
A
LayoutTests/http/tests/site-isolation/resources/audio-session-playback-frame.html
A
LayoutTests/http/tests/site-isolation/resources/report-video-element-audio-session-category.html
M LayoutTests/media/audioSession/audioSessionType.html
M LayoutTests/media/utilities.js
M Source/WebCore/Modules/audiosession/DOMAudioSession.cpp
M Source/WebCore/Modules/audiosession/DOMAudioSession.h
M Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp
M Source/WebCore/Modules/mediastream/UserMediaRequest.cpp
M Source/WebCore/html/HTMLMediaElement.cpp
M Source/WebCore/html/HTMLMediaElement.h
M Source/WebCore/page/Page.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/cocoa/MediaSessionManagerCocoa.h
M Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm
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/UIProcess/Media/RemoteMediaSessionManagerProxy.cpp
M Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.h
M Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.messages.in
M
Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.cpp
M Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.h
M Source/WebKit/WebProcess/Media/RemoteMediaSessionManager.cpp
M Source/WebKit/WebProcess/Media/RemoteMediaSessionManager.h
M Source/WebKit/WebProcess/Media/RemoteMediaSessionManager.messages.in
M
Tools/TestWebKitAPI/Tests/WebKit/WKWebView/GetDisplayMediaWindowAndScreen.mm
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/GetUserMedia.mm
Log Message:
-----------
[site-isolation] AudioSession category should be calculated synchronously and
not wait for the UI process
https://bugs.webkit.org/show_bug.cgi?id=321642
rdar://184769561
Reviewed by Eric Carlson.
301864@main removed the audio session category calculation from the content
process. 303417@main made
RemoteMediaSessionManagerProxy a MediaSessionManagerCocoa and a
WebCore::AudioSession without
overriding updateSessionState(), so the UI process computed the category and
pushed it back, and
317396@main made that proxy a singleton, so one category covered every page of
every process. The
content process learned its category from an asynchronous IPC reply, which
caused two classes of
problem.
1) Scripts read a stale category, since internals.audioSessionCategory() reads
this process's
AudioSession and could run before the reply arrived. Every path reading it
after an await needed
its own fix: play(), getUserMedia, track mute/unmute, the audioTracks change
event, the
navigator.audioSession.type override, and the category recorded at the most
recent playback.
2) Operations with no reason to be asynchronous became asynchronous to
accommodate it:
updateSessionState() returned a GenericPromise, three IPC replies carried
(category, mode, policy),
the proxy pushed the category to every process, and the getUserMedia resolution
and the mute/unmute
event dispatch were gated on a promise waiting on getting the new category.
The UI process has no
information of a kind the content process lacks: the calculation reads no
AVAudioSession, no audio route, and no interruption or application state, only
media session
bookkeeping. Its only advantage was breadth, the sessions of other content
processes, and the GPU
process already reconciles that by collecting the category each process reports
and applying the
highest priority one. Every branch of the calculation tests whether at least
one session is doing
something, so a process seeing only its own sessions lands at or below the
correct category and never
above it, which makes the highest-priority pick equivalent to calculating over
every process's
sessions.
RemoteMediaSessionManager::updateSessionState() chains to
MediaSessionManagerCocoa, applying the
category in the same turn, and sends the session states and the capture count
to the UI process
without waiting for a reply as the UI process still needs them for playback
admission and activation.
The proxy computes no
category of its own: its updateSessionState() does nothing, and the category in
the AddMediaSession, UpdateMediaSessionStates and MediaSessionWillBeginPlayback
replies, the
SetAudioSessionCategory push, and the per-page override tracking are all
removed. updateSessionState()
can now return void.
DocumentSyncData already synchronized navigator.audioSession.type to every
process of the page. Each
process converts that type into a category override and applies it in its own
calculation, so every
process of a page computes with the same override.
This removes a difference that existed only with site isolation enabled. The UI
process used the
override of any page that had set one, so navigator.audioSession.type in one
page lowered the category
for unrelated pages in other processes. Without site isolation the override
lives on the web process's
own AudioSession and never reached a page in another process, and the GPU
process's pick can only
raise, so an override there has
never lowered another process's category. The two configurations now
behave the same.
The tests read the category applied to the real audio session with a new
internals.systemAudioSessionCategory(), which returns a promise because that
category lives in the
process owning the session, over IPC gated on AllowTestOnlyIPC.
http/tests/site-isolation/audio-session-category-override-does-not-affect-another-page.html
covers the
paragraph above: this page sets the type and plays nothing, a page opened in
another process plays
audible media, and that page still computes MediaPlayback while the real
session takes it. Before this
change both pages took the category the UI process computed from the override,
so both read
AmbientSound.
audio-session-category-override-and-playback.html and
audio-session-category-override-after-playback.html cover the two ways the type
reaches another process
of the same page, the state that process is created with and the per-field
DocumentSyncData
broadcast,
and assert that the override replaces the computed category in both directions.
Neither enables site
isolation, so the site-isolated run is compared against the same expectations
as the ordinary one: with
site isolation the frames are in separate processes and the type reaches the
playing one through
DocumentSyncData, without it they share a process and its audio session.
audio-session-category-capture-and-playback.html covers the reconciliation this
change relies on: one
process plays audible media, another captures the microphone, each computes the
category for its own
sessions, and the real audio session resolves to PlayAndRecord.
playPlayer() reads the category directly, as setState(State::Playing) notifies
the manager and
sessionStateChanged() calls updateSessionState() synchronously before
clientWillBeginPlayback()'s
completion reaches updatePlayState().
The wait in UserMediaRequest::allow() and on the track unmute event stays and
now covers the
audio
session activation alone: 318776@main added it for activation, which failed at
45% without site
isolation, and activation remains asynchronous. The API tests keep their waits
around unmuting for the
same reason, and lose those around muting and around screen capture.
Reverted in full: 317945@main.
Reverted in part: 301864@main, 303417@main, 317760@main, 318099@main,
318537@main, 318776@main,
318865@main, 319003@main.
*
LayoutTests/http/tests/site-isolation/audio-session-category-capture-and-playback-expected.txt:
Added.
*
LayoutTests/http/tests/site-isolation/audio-session-category-capture-and-playback.html:
Added.
*
LayoutTests/http/tests/site-isolation/audio-session-category-override-after-playback-expected.txt:
Added.
*
LayoutTests/http/tests/site-isolation/audio-session-category-override-after-playback.html:
Added.
*
LayoutTests/http/tests/site-isolation/audio-session-category-override-and-playback-expected.txt:
Added.
*
LayoutTests/http/tests/site-isolation/audio-session-category-override-and-playback.html:
Added.
*
LayoutTests/http/tests/site-isolation/audio-session-category-override-does-not-affect-another-page-expected.txt:
Added.
*
LayoutTests/http/tests/site-isolation/audio-session-category-override-does-not-affect-another-page.html:
Added.
*
LayoutTests/http/tests/site-isolation/resources/audio-session-capture-frame.html:
Added.
*
LayoutTests/http/tests/site-isolation/resources/audio-session-playback-frame.html:
Added.
*
LayoutTests/http/tests/site-isolation/resources/report-video-element-audio-session-category.html:
Added.
* LayoutTests/media/audioSession/audioSessionType.html: Use
waitForAudioSessionCategory() instead of a
local copy.
* LayoutTests/media/utilities.js: Added waitForAudioSessionCategory() and
waitForSystemAudioSessionCategory().
* Source/WebCore/Modules/audiosession/DOMAudioSession.cpp:
(WebCore::DOMAudioSession::applyTypeToAudioSessionCategoryOverride): Added.
Apply
the category
override a type implies to this process's audio session.
* Source/WebCore/Modules/audiosession/DOMAudioSession.h:
* Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp:
(WebCore::MediaStreamTrack::trackMutedChanged): Wait for the audio session
activation only when
unmuting an audio capture track, and queue the event directly otherwise.
* Source/WebCore/Modules/mediastream/UserMediaRequest.cpp:
(WebCore::UserMediaRequest::allow): Wait for the audio session activation
instead of the category.
* Source/WebCore/html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::categoryDidChange): Deleted.
* Source/WebCore/html/HTMLMediaElement.h:
* Source/WebCore/page/Page.cpp:
(WebCore::Page::updateTopDocumentSyncData): Apply the category override implied
by a synchronized
audio session type, on both the per-field and the whole-state path.
* Source/WebCore/platform/audio/AudioSession.h:
(WebCore::AudioSessionConfigurationChangeObserver::categoryDidChange):
Deleted.
(WebCore::AudioSession::systemCategoryForTesting): Added. Return the category
of this process's audio
session, overridden where that session lives in another process.
* Source/WebCore/platform/audio/MediaSessionManagerInterface.cpp:
(WebCore::MediaSessionManagerInterface::audioCaptureSourceStateChanged): Return
a promise covering the
activation.
(WebCore::MediaSessionManagerInterface::updateSessionState): Deleted; the empty
body moves back to the
header.
* Source/WebCore/platform/audio/MediaSessionManagerInterface.h:
* Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h:
* Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm:
(WebCore::MediaSessionManagerCocoa::updateSessionState): Return void.
* Source/WebCore/testing/Internals.cpp:
(WebCore::Internals::systemAudioSessionCategory): Added.
* Source/WebCore/testing/Internals.h:
* Source/WebCore/testing/Internals.idl:
*
Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.cpp:
(WebKit::RemoteAudioSessionProxy::systemCategoryForTesting): Added. Reply with
the category applied to
the real audio session.
* Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.h:
* Source/WebKit/GPUProcess/media/RemoteAudioSessionProxy.messages.in:
* Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.cpp:
(WebKit::RemoteMediaSessionManagerProxy::RemoteMediaSessionManagerProxy): Don't
set
shouldManageAudioSessionCategory; the UI process computes no category.
(WebKit::RemoteMediaSessionManagerProxy::addMediaSession): Don't reply with the
category.
(WebKit::RemoteMediaSessionManagerProxy::webProcessWillShutDown): Drop the
per-page override cleanup.
(WebKit::RemoteMediaSessionManagerProxy::updateMediaSessionStates): Don't track
the override, compute
the category or reply with it.
(WebKit::RemoteMediaSessionManagerProxy::mediaSessionWillBeginPlayback): Reply
with the admission
decision
only.
(WebKit::RemoteMediaSessionManagerProxy::categoryOverride): Deleted.
(WebKit::RemoteMediaSessionManagerProxy::setCategory): Deleted.
* Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.h:
* Source/WebKit/UIProcess/Media/RemoteMediaSessionManagerProxy.messages.in:
* Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.cpp:
(WebKit::RemoteAudioSession::setCategory): Don't notify the configuration
change observers.
(WebKit::RemoteAudioSession::systemCategoryForTesting): Added. Ask the process
owning the session.
* Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.h:
* Source/WebKit/WebProcess/Media/RemoteMediaSessionManager.cpp:
(WebKit::RemoteMediaSessionManager::addSession): Send without a reply.
(WebKit::RemoteMediaSessionManager::sessionWillBeginPlayback): Take the
admission decision only.
(WebKit::RemoteMediaSessionManager::updateSessionState): Compute the category
in this process.
(WebKit::RemoteMediaSessionManager::setAudioSessionCategory):
Deleted.
* Source/WebKit/WebProcess/Media/RemoteMediaSessionManager.h:
* Source/WebKit/WebProcess/Media/RemoteMediaSessionManager.messages.in:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/GetDisplayMediaWindowAndScreen.mm:
(TestWebKitAPI::armActionState): Deleted.
(TestWebKitAPI::waitForActionState): Deleted.
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/GetUserMedia.mm:
Canonical link:
https://flagged.apple.com:443/proxy?t2=DY0e8E3cy3&o=aHR0cHM6Ly9jb21taXRzLndlYmtpdC5vcmcvMzE5MjMwQG1haW4=&emid=adbfbc9d-7e7f-44d3-97c9-e89d0ebe2bba&c=11
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications