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

Reply via email to