Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 041d3443858bb3cfa03f843a2fcd998ccbda223a
      
https://github.com/WebKit/WebKit/commit/041d3443858bb3cfa03f843a2fcd998ccbda223a
  Author: Eric Carlson <[email protected]>
  Date:   2026-08-20 (Thu, 20 Aug 2026)

  Changed paths:
    A 
LayoutTests/http/tests/site-isolation/now-playing-elected-across-frames-expected.txt
    A 
LayoutTests/http/tests/site-isolation/now-playing-elected-across-frames.html
    A 
LayoutTests/http/tests/site-isolation/now-playing-reelects-on-resize-expected.txt
    A LayoutTests/http/tests/site-isolation/now-playing-reelects-on-resize.html
    A LayoutTests/http/tests/site-isolation/resources/now-playing-frame.html
    M Source/WebCore/html/MediaElementSession.cpp
    M Source/WebCore/html/MediaElementSession.h
    M Source/WebCore/platform/MediaStrategy.cpp
    M Source/WebCore/platform/MediaStrategy.h
    M Source/WebCore/platform/NowPlayingManager.cpp
    M Source/WebCore/platform/NowPlayingManager.h
    M Source/WebCore/platform/audio/NowPlayingInfo.h
    M Source/WebCore/platform/audio/PlatformMediaSessionInterface.cpp
    M Source/WebCore/platform/audio/PlatformMediaSessionInterface.h
    M Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h
    M Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm
    M Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.cpp
    M Source/WebCore/testing/Internals.cpp
    M Source/WebCore/testing/Internals.h
    M Source/WebCore/testing/Internals.idl
    M Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp
    M Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h
    M Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in
    M Source/WebKit/GPUProcess/GPUProcess.cpp
    M Source/WebKit/GPUProcess/GPUProcess.h
    M Source/WebKit/Scripts/webkit/messages.py
    M Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in
    M Source/WebKit/WebProcess/GPU/media/WebMediaStrategy.cpp
    M Source/WebKit/WebProcess/GPU/media/WebMediaStrategy.h

  Log Message:
  -----------
  [Site Isolation] Elect the NowPlaying session in the GPU process
https://bugs.webkit.org/show_bug.cgi?id=321966
rdar://171748880

Reviewed by Jean-Yves Avenard.

There is exactly one system NowPlaying session per app, but the GPU process's
NowPlayingManager holds a single client slot: whichever web process pushes its
NowPlaying info last becomes NowPlaying and receives remote-control commands.
When a page has more than one element eligible to be the NowPlaying session,
WebKit chooses the best candidate based on the session's characteristics: size,
whether or not it is playing, has audio, etc. With site isolation a top-level
page's cross-origin subframes run in separate processes so the selection logic
can't run in the web process or an audible subframe could take over NowPlaying
and its remote commands from a "more eligible" session in the same page but
running in another process.

Each web process already chooses its own best NowPlaying session in
MediaSessionManagerCocoa::updateNowPlayingInfo and sends it to the GPU process. 
This
change updates the GPU process so it doesn't just choose the most recent 
session pushed
to it, but instead chooses the most eligible session from the per-page winners:

- A page's candidate and its NowPlaying info are reported separately.
  SetNowPlayingCandidateState carries the winning session's page and session 
identifiers
  plus the comparator inputs the election reads (presentationType,
  isLargeEnoughForMainContent, isPlaying, and the most-recent user-interaction 
time as a
  WallTime, since MonotonicTime is not comparable across processes); the GPU 
process
  updates that page's candidate and re-runs the election. 
SetNowPlayingInfoForPage
  carries the NowPlayingInfo and page identifier; the GPU process updates that 
page's
  info and, when the page owns NowPlaying, pushes it straight to 
NowPlayingManager
  without re-electing. ClearNowPlayingInfoForPage withdraws a page's candidate. 
Candidacy
  is reported whenever it changes, independent of the info-update throttling, 
so resizing
  a paused video (which changes its eligibility but not its info) still re-runs 
the
  election.

- GPUConnectionToWebProcess keeps its process's per-page candidates; on any 
change
  GPUProcess::recomputeNowPlayingOwner picks the single winner using the same 
tiered
  order as PlatformMediaSessionManager::bestEligibleSessionForRemoteControls and
  HTMLMediaElement::selectBestMediaSession, preferring the current owner when 
candidates
  are otherwise equal so the choice is stable.

- The candidates are keyed by { process, page } so a process hosting several 
pages is
  handled correctly.

- The GPU process enables arbitration itself from shared preferences
  (remoteMediaSessionManagerEnabled || siteIsolationEnabled); the flag is 
process-wide
  and sticky so a non-isolated process cannot take the panel from the election. 
Without
  it, each process self-designates on push, preserving the existing behavior.

For test observability, internals.elementIsActiveNowPlayingSessionInGPUProcess 
asks
the GPU process whether a given element's session is the elected system owner, 
so
a test can assert the session chosen by the GPU process rather than a value the 
content
process set itself.

Cross-process playback interruption is unchanged; the layout tests exercise it 
together
with the NowPlaying takeover, and the re-election when a paused candidate is 
resized.

Tests: http/tests/site-isolation/now-playing-elected-across-frames.html
       http/tests/site-isolation/now-playing-reelects-on-resize.html

* 
LayoutTests/http/tests/site-isolation/now-playing-elected-across-frames-expected.txt:
 Added.
* LayoutTests/http/tests/site-isolation/now-playing-elected-across-frames.html: 
Added.
* 
LayoutTests/http/tests/site-isolation/now-playing-reelects-on-resize-expected.txt:
 Added.
* LayoutTests/http/tests/site-isolation/now-playing-reelects-on-resize.html: 
Added.
* LayoutTests/http/tests/site-isolation/resources/now-playing-frame.html: Added.
* Source/WebCore/html/MediaElementSession.cpp:
(WebCore::isElementLargeEnoughForMainContent):
* Source/WebCore/html/MediaElementSession.h:
* Source/WebCore/platform/MediaStrategy.cpp:
(WebCore::MediaStrategy::isActiveNowPlayingSessionInGPUProcessForTesting):
* Source/WebCore/platform/MediaStrategy.h:
* Source/WebCore/platform/NowPlayingManager.cpp:
(WebCore::NowPlayingManager::clearNowPlayingInfoForPage):
(WebCore::NowPlayingManager::clearNowPlayingInfoPrivate):
(WebCore::NowPlayingManager::setNowPlayingInfo):
(WebCore::NowPlayingManager::updateNowPlayingCandidateState):
(WebCore::NowPlayingManager::setNowPlayingInfoPrivate):
* Source/WebCore/platform/NowPlayingManager.h:
* Source/WebCore/platform/audio/NowPlayingInfo.h:
* Source/WebCore/platform/audio/PlatformMediaSessionInterface.cpp:
(WebCore::PlatformMediaSessionInterface::isLargeEnoughForMainContent const):
(WebCore::PlatformMediaSessionInterface::mostRecentUserInteractionTime const):
* Source/WebCore/platform/audio/PlatformMediaSessionInterface.h:
* Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h:
* Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm:
(WebCore::MediaSessionManagerCocoa::updateNowPlayingInfo):
* Source/WebCore/platform/audio/glib/MediaSessionManagerGLib.cpp:
(WebCore::MediaSessionManagerGLib::updateNowPlayingInfo):
* Source/WebCore/testing/Internals.cpp:
(WebCore::Internals::elementIsActiveNowPlayingSessionInGPUProcess):
* Source/WebCore/testing/Internals.h:
* Source/WebCore/testing/Internals.idl:
* Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp:
(WebKit::GPUConnectionToWebProcess::clearNowPlayingInfoForPage):
(WebKit::GPUConnectionToWebProcess::setNowPlayingCandidateState):
(WebKit::GPUConnectionToWebProcess::setNowPlayingInfoForPage):
(WebKit::GPUConnectionToWebProcess::becomeNowPlayingOwner):
(WebKit::GPUConnectionToWebProcess::resignNowPlayingOwner):
(WebKit::GPUConnectionToWebProcess::isActiveNowPlayingSessionForTesting):
* Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h:
* Source/WebKit/GPUProcess/GPUConnectionToWebProcess.messages.in:
* Source/WebKit/GPUProcess/GPUProcess.cpp:
(WebKit::GPUProcess::createGPUConnectionToWebProcess):
(WebKit::GPUProcess::updateNowPlayingArbiterActive):
(WebKit::GPUProcess::sharedPreferencesForWebProcessDidChange):
(WebKit::GPUProcess::removeGPUConnectionToWebProcess):
(WebKit::GPUProcess::recomputeNowPlayingOwner):
* Source/WebKit/GPUProcess/GPUProcess.h:
* Source/WebKit/Scripts/webkit/messages.py:
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:
* Source/WebKit/WebProcess/GPU/media/WebMediaStrategy.cpp:
(WebKit::WebMediaStrategy::createNowPlayingManager):
(WebKit::WebMediaStrategy::isActiveNowPlayingSessionInGPUProcessForTesting):
* Source/WebKit/WebProcess/GPU/media/WebMediaStrategy.h:

Canonical link: https://commits.webkit.org/319542@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to