Skip to content
Permalink
Browse files
A HTMLMediaElement created while page is interrupted should be able t…
…o autoplay

https://bugs.webkit.org/show_bug.cgi?id=241783

Patch by Youenn Fablet <youennf@gmail.com> on 2022-06-21
Reviewed by Eric Carlson.

Previously, a session created while manager is interrupted would get its state set to interrupted.
When end of interruption happens, it would not be restarted since its interruption count would be set to 0.
Instead, manager now stores the last interruption.
In case of a new session, we now call beginInterruption instead of setting the session state directly.
This allows to have an interruption count set to 1 and thus uninterrupt the session when the end of interruption signal happens.

Covered by added test.

* LayoutTests/fast/mediastream/video-created-while-interrupted-expected.txt: Added.
* LayoutTests/fast/mediastream/video-created-while-interrupted.html: Added.
* Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp:
(WebCore::PlatformMediaSessionManager::beginInterruption):
(WebCore::PlatformMediaSessionManager::endInterruption):
(WebCore::PlatformMediaSessionManager::addSession):
(WebCore::PlatformMediaSessionManager::sessionWillBeginPlayback):
(WebCore::PlatformMediaSessionManager::processSystemWillSleep):
(WebCore::PlatformMediaSessionManager::processSystemDidWake):
* Source/WebCore/platform/audio/PlatformMediaSessionManager.h:
(WebCore::PlatformMediaSessionManager::isInterrupted const):

Canonical link: https://commits.webkit.org/251691@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295686 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
youennf authored and webkit-commit-queue committed Jun 21, 2022
1 parent 5ba989b commit 21d50bf
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 9 deletions.
@@ -0,0 +1,4 @@


PASS Correctly handle autoplay for a media element created while page is interrupted

@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Capture source interruption.</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
promise_test(async (test) => {
if (window.internals)
internals.beginAudioSessionInterruption();

const video = document.createElement('video');
video.autoplay = true;
document.body.appendChild(video);

const stream = await navigator.mediaDevices.getUserMedia({audio: true});
video.srcObject = stream;

let counter = 0;
while(++counter < 100 && video.paused)
await new Promise(resolve => setTimeout(resolve, 50));

assert_false(video.paused);
}, "Correctly handle autoplay for a media element created while page is interrupted");
</script>
</body>
</html>
@@ -156,7 +156,7 @@ void PlatformMediaSessionManager::beginInterruption(PlatformMediaSession::Interr
{
ALWAYS_LOG(LOGIDENTIFIER);

m_interrupted = true;
m_currentInterruption = type;
forEachSession([type] (auto& session) {
session.beginInterruption(type);
});
@@ -167,7 +167,7 @@ void PlatformMediaSessionManager::endInterruption(PlatformMediaSession::EndInter
{
ALWAYS_LOG(LOGIDENTIFIER);

m_interrupted = false;
m_currentInterruption = { };
forEachSession([flags] (auto& session) {
session.endInterruption(flags);
});
@@ -177,8 +177,8 @@ void PlatformMediaSessionManager::addSession(PlatformMediaSession& session)
{
ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier());
m_sessions.append(session);
if (m_interrupted)
session.setState(PlatformMediaSession::Interrupted);
if (m_currentInterruption)
session.beginInterruption(*m_currentInterruption);

#if !RELEASE_LOG_DISABLED
m_logger->addLogger(session.logger());
@@ -243,7 +243,7 @@ bool PlatformMediaSessionManager::sessionWillBeginPlayback(PlatformMediaSession&
return false;
}

if (m_interrupted)
if (m_currentInterruption)
endInterruption(PlatformMediaSession::NoFlags);

if (restrictions & ConcurrentPlaybackNotPermitted) {
@@ -455,7 +455,7 @@ bool PlatformMediaSessionManager::computeSupportsSeeking() const

void PlatformMediaSessionManager::processSystemWillSleep()
{
if (m_interrupted)
if (m_currentInterruption)
return;

forEachSession([] (auto& session) {
@@ -465,7 +465,7 @@ void PlatformMediaSessionManager::processSystemWillSleep()

void PlatformMediaSessionManager::processSystemDidWake()
{
if (m_interrupted)
if (m_currentInterruption)
return;

forEachSession([] (auto& session) {
@@ -157,7 +157,7 @@ class PlatformMediaSessionManager

WEBCORE_EXPORT void processDidReceiveRemoteControlCommand(PlatformMediaSession::RemoteControlCommandType, const PlatformMediaSession::RemoteCommandArgument&);

bool isInterrupted() const { return m_interrupted; }
bool isInterrupted() const { return !!m_currentInterruption; }
bool hasNoSession() const;

virtual void addSupportedCommand(PlatformMediaSession::RemoteControlCommandType) { };
@@ -209,7 +209,7 @@ class PlatformMediaSessionManager
SessionRestrictions m_restrictions[static_cast<unsigned>(PlatformMediaSession::MediaType::WebAudio) + 1];
mutable Vector<WeakPtr<PlatformMediaSession>> m_sessions;

bool m_interrupted { false };
std::optional<PlatformMediaSession::InterruptionType> m_currentInterruption;
mutable bool m_isApplicationInBackground { false };
bool m_willIgnoreSystemInterruptions { false };
bool m_processIsSuspended { false };

0 comments on commit 21d50bf

Please sign in to comment.