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