Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: a09645c2ee47c1aa9191f8fba1a0c60ce3cdc10e
      
https://github.com/WebKit/WebKit/commit/a09645c2ee47c1aa9191f8fba1a0c60ce3cdc10e
  Author: Jean-Yves Avenard <[email protected]>
  Date:   2026-09-30 (Wed, 30 Sep 2026)

  Changed paths:
    A LayoutTests/media/media-playback-in-background-after-pausing-expected.txt
    A LayoutTests/media/media-playback-in-background-after-pausing.html
    A LayoutTests/media/media-playback-in-background-handover-expected.txt
    A LayoutTests/media/media-playback-in-background-handover.html
    A 
LayoutTests/media/media-source/media-source-hidden-already-playing-not-paused-expected.txt
    A 
LayoutTests/media/media-source/media-source-hidden-already-playing-not-paused.html
    A 
LayoutTests/media/media-source/media-source-hidden-play-before-data-expected.txt
    A LayoutTests/media/media-source/media-source-hidden-play-before-data.html
    A LayoutTests/media/video-system-sleep-hidden-expected.txt
    A LayoutTests/media/video-system-sleep-hidden.html
    M Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml
    M Source/WebCore/dom/Document.h
    M Source/WebCore/html/HTMLMediaElement.cpp
    M Source/WebCore/html/HTMLMediaElement.h
    M Source/WebCore/html/MediaElementSession.cpp
    M Source/WebCore/html/MediaElementSession.h
    M Source/WebCore/testing/Internals.cpp
    M Source/WebCore/testing/Internals.h
    M Source/WebCore/testing/Internals.idl
    M Source/WebKit/Shared/WebPreferencesDefaultValues.cpp
    M Source/WebKit/Shared/WebPreferencesDefaultValues.h
    M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/NowPlayingSession.mm
    M 
Tools/TestWebKitAPI/Tests/WebKit/WKWebView/RequiresUserActionForPlayback.mm
    M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm
    M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WebsitePolicies.mm

  Log Message:
  -----------
  YouTube started autoplaying in background tab
https://bugs.webkit.org/show_bug.cgi?id=310600
rdar://169468617

Reviewed by Youenn Fablet.

A video that the user had paused, in a window that was then minimised, could 
start playing
again without any user interaction: nothing required a user gesture to start 
playback in a
hidden page.

Add a behavior restriction, RequireUserGestureToStartAudiblePlaybackWhenHidden, 
controlled by
a new embedder setting of the same name that defaults to true. While the 
document is hidden
and no user gesture is being processed, a request to start audible playback is 
denied. A
gesture inherited from an earlier interaction with the document, through the
MediaUserGestureInheritsFromDocument setting or the InheritedUserGestures 
autoplay quirk, does
not count. The check runs before the autoplay quirks and the main content 
override, which would
otherwise allow the playback. The restriction does not apply when:
- the element is not paused, or its session is already Playing. Media that is 
playing, whose
  play() was already accepted and is still waiting for data, or whose session 
is restored to
  Playing when an interruption such as system sleep ends, is never denied;
- the element is muted, has a zero volume, is a video known to have no audio, 
or plays a
  MediaStream. Before metadata is available the element is treated as audible;
- another element of the same document is playing audio;
- this element stopped playing, or another element of the same document stopped 
playing
  audibly, within the last 10 seconds, so a playlist can move to its next item 
on the same or
  another element;
- the element autoplays a load that started within those 10 seconds. Only the 
autoplay itself
  is allowed, whenever its data arrives and on every path that starts it; a 
script play()
  during that load is not.

RequiresUserActionForPlayback put its WKWebView in a window that was never 
shown, so its pages
were hidden. With the new restriction, the tests that do not require a user 
gesture for audio
playback saw their audio-only page refused when it started playing without a 
gesture.
createWebView() now uses a TestWKWebView in a window that is shown, and waits 
for the view to be
visible before loading. The API tests that start audible playback without a 
gesture disable
window occlusion detection, so that a covered test window does not make their 
page hidden.

media-playback-in-background-handover.html keeps the page hidden for its iframe 
step. Showing the
page restarted elements that the test had played and paused while hidden: their 
play() committed
State::Playing while the page visibility interruption was active, pause() left 
the state to
restore at Playing, and ending the interruption resumed them. The test carries 
a FIXME for
webkit.org/b/325646.

Tests: media/media-playback-in-background-after-pausing.html
       media/media-playback-in-background-handover.html
       media/media-source/media-source-hidden-already-playing-not-paused.html
       media/media-source/media-source-hidden-play-before-data.html
       media/video-system-sleep-hidden.html
       
TestWebKitAPI.WebpagePreferences.WebsitePoliciesAutoplayQuirksDoNotStartAudiblePlaybackWhenHidden

* LayoutTests/media/media-playback-in-background-after-pausing-expected.txt: 
Added.
* LayoutTests/media/media-playback-in-background-after-pausing.html: Added.
* LayoutTests/media/media-playback-in-background-handover-expected.txt: Added.
* LayoutTests/media/media-playback-in-background-handover.html: Added.
* 
LayoutTests/media/media-source/media-source-hidden-already-playing-not-paused-expected.txt:
 Added.
* 
LayoutTests/media/media-source/media-source-hidden-already-playing-not-paused.html:
 Added.
* 
LayoutTests/media/media-source/media-source-hidden-play-before-data-expected.txt:
 Added.
* LayoutTests/media/media-source/media-source-hidden-play-before-data.html: 
Added.
* LayoutTests/media/video-system-sleep-hidden-expected.txt: Added.
* LayoutTests/media/video-system-sleep-hidden.html: Added.
* Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml: Add 
RequiresUserGestureToStartAudiblePlaybackWhenHidden.
* Source/WebCore/dom/Document.h:
(WebCore::Document::audiblePlaybackEnded): Added.
(WebCore::Document::mostRecentAudiblePlaybackEndedTime const): Added.
* Source/WebCore/html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::initializeMediaSession): Add the restriction when 
the setting is enabled.
(WebCore::HTMLMediaElement::prepareForLoad): Tell the session a load is 
starting and whether it autoplays.
(WebCore::HTMLMediaElement::canTransitionFromAutoplayToPlay const): Ask for 
permission on behalf of autoplay.
(WebCore::HTMLMediaElement::play):
(WebCore::HTMLMediaElement::playIfPermitted): Added. Ask for permission on 
behalf of autoplay when requested.
(WebCore::HTMLMediaElement::resumeAutoplaying): Start playback on behalf of 
autoplay.
(WebCore::HTMLMediaElement::updateShouldPlay): Ditto.
(WebCore::HTMLMediaElement::mediaStreamCaptureStarted): Ditto.
* Source/WebCore/html/HTMLMediaElement.h:
* Source/WebCore/html/MediaElementSession.cpp:
(WebCore::restrictionNames):
(WebCore::MediaElementSession::playbackStateChangePermitted const): Deny 
starting audible playback while hidden,
before any quirk or override can allow it.
(WebCore::MediaElementSession::setState): Record when playback stops, on the 
document too when it was audible;
clear the autoplay grant once playing.
(WebCore::MediaElementSession::isWithinGracePeriodForResumingPlaybackInBackground
 const): Added.
(WebCore::MediaElementSession::loadWillStart): Added. Grant an autoplay load 
started within the grace period.
(WebCore::isProcessingUserGestureForStartingPlaybackWhileHidden): Added. Only 
count a current or recent gesture.
(WebCore::MediaElementSession::startingAudiblePlaybackWhileHiddenRequiresUserGesture
 const): Added.
* Source/WebCore/html/MediaElementSession.h:
(WebCore::MediaElementSession::gracePeriodForResumingPlaybackInBackground 
const):
(WebCore::MediaElementSession::setGracePeriodForResumingPlaybackInBackgroundForTesting):
* Source/WebCore/testing/Internals.cpp:
(WebCore::Internals::setMediaElementRestrictions):
(WebCore::Internals::setMediaElementGracePeriodForResumingPlaybackInBackground):
* Source/WebCore/testing/Internals.h:
* Source/WebCore/testing/Internals.idl:
* Source/WebKit/Shared/WebPreferencesDefaultValues.cpp:
(WebKit::defaultRequiresUserGestureToStartAudiblePlaybackWhenHidden):
* Source/WebKit/Shared/WebPreferencesDefaultValues.h:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/NowPlayingSession.mm:
(createWebViewInItsOwnWebContentProcess): Disable window occlusion detection.
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/RequiresUserActionForPlayback.mm:
(RequiresUserActionForPlaybackTest::createWebView): Use a visible TestWKWebView 
so the pages are not hidden.
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/SiteIsolation.mm:
(TestWebKitAPI::TEST(SiteIsolation, 
AutoplayPolicyInRemoteFrameFollowsMainFrame)): Disable window occlusion 
detection.
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/WebsitePolicies.mm:
(TEST(WebpagePreferences, 
WebsitePoliciesAutoplayQuirksDoNotStartAudiblePlaybackWhenHidden)): Added.

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



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

Reply via email to