Diff
Modified: trunk/LayoutTests/ChangeLog (245711 => 245712)
--- trunk/LayoutTests/ChangeLog 2019-05-23 20:44:06 UTC (rev 245711)
+++ trunk/LayoutTests/ChangeLog 2019-05-23 20:56:56 UTC (rev 245712)
@@ -1,3 +1,14 @@
+2019-05-23 Youenn Fablet <[email protected]>
+
+ Multiple videos (with audios) with autoplay & playinline not working. Only one video play at a time.
+ https://bugs.webkit.org/show_bug.cgi?id=193312
+ <rdar://problem/47189864>
+
+ Reviewed by Jer Noble.
+
+ * webrtc/concurrentVideoPlayback-expected.txt: Added.
+ * webrtc/concurrentVideoPlayback.html: Added.
+
2019-05-23 Shawn Roberts <[email protected]>
Updating test expectations for failing tests.
Added: trunk/LayoutTests/webrtc/concurrentVideoPlayback-expected.txt (0 => 245712)
--- trunk/LayoutTests/webrtc/concurrentVideoPlayback-expected.txt (rev 0)
+++ trunk/LayoutTests/webrtc/concurrentVideoPlayback-expected.txt 2019-05-23 20:56:56 UTC (rev 245712)
@@ -0,0 +1,7 @@
+
+
+PASS Basic audio/video exchange
+PASS Play MediaStream backed streams concurrently
+PASS Play regular video content should pause MediaStream backed video elements
+PASS Play MediaStream backed video elements should pause regular video content
+
Added: trunk/LayoutTests/webrtc/concurrentVideoPlayback.html (0 => 245712)
--- trunk/LayoutTests/webrtc/concurrentVideoPlayback.html (rev 0)
+++ trunk/LayoutTests/webrtc/concurrentVideoPlayback.html 2019-05-23 20:56:56 UTC (rev 245712)
@@ -0,0 +1,80 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Testing concurrent video playing</title>
+ <script src=""
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <video id="video1" autoplay controls></video>
+ <video id="video2" autoplay controls></video>
+ <video id="video3" autoplay controls></video>
+ <script src =""
+ <script>
+promise_test(async (test) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+
+ localStream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
+
+ const remoteStream = await new Promise((resolve, reject) => {
+ createConnections((firstConnection) => {
+ firstConnection.addTrack(localStream.getVideoTracks()[0], localStream);
+ firstConnection.addTrack(localStream.getAudioTracks()[0], localStream);
+ }, (secondConnection) => {
+ secondConnection._ontrack_ = (trackEvent) => {
+ resolve(trackEvent.streams[0]);
+ };
+ });
+ setTimeout(() => reject("Test timed out"), 5000);
+ });
+
+ video1.srcObject = localStream;
+ video2.srcObject = remoteStream;
+}, "Basic audio/video exchange");
+
+promise_test(async (test) => {
+ await video1.play();
+ await video2.play();
+
+ assert_false(video1.paused, "video1 paused");
+ assert_false(video2.paused, "video2 paused");
+}, "Play MediaStream backed streams concurrently");
+
+promise_test(async (test) => {
+
+ if (window.internals)
+ internals.setMediaSessionRestrictions('videoaudio', 'ConcurrentPlaybackNotPermitted');
+
+ video3.src = "" '../media/content/audio-tracks');
+ await video3.play();
+
+ let counter = 0;
+ while (!video1.paused && ++counter < 20)
+ await new Promise(resolve => setTimeout(resolve, 50));
+
+ assert_true(video1.paused, "video1 paused");
+ assert_true(video2.paused, "video2 paused");
+ assert_false(video3.paused, "video3 paused");
+}, "Play regular video content should pause MediaStream backed video elements");
+
+promise_test(async (test) => {
+ await video1.play();
+
+ assert_true(video3.paused, "video3 paused");
+
+ await video2.play();
+
+ let counter = 0;
+ while (!video3.paused && ++counter < 20)
+ await new Promise(resolve => setTimeout(resolve, 50));
+
+ assert_false(video1.paused, "video1 paused");
+ assert_false(video2.paused, "video2 paused");
+ assert_true(video3.paused, "video3 paused");
+}, "Play MediaStream backed video elements should pause regular video content");
+ </script>
+ </body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (245711 => 245712)
--- trunk/Source/WebCore/ChangeLog 2019-05-23 20:44:06 UTC (rev 245711)
+++ trunk/Source/WebCore/ChangeLog 2019-05-23 20:56:56 UTC (rev 245712)
@@ -1,3 +1,82 @@
+2019-05-23 Youenn Fablet <[email protected]>
+
+ Multiple videos (with audios) with autoplay & playinline not working. Only one video play at a time.
+ https://bugs.webkit.org/show_bug.cgi?id=193312
+ <rdar://problem/47189864>
+
+ Reviewed by Jer Noble.
+
+ Allow all MediaStream backed video elements to play together.
+ Any non MediaStream backed video will stop all MediaStream backed video elements.
+ Conversely, all non MediaStream backed videos will stop when playing one MediaStream backed video.
+
+ Refactor PlatformMediaSessionManager as the way to iterate through sessions
+ is not safe when pausing a session: if playing, the session will be moved in the array of sessions.
+
+ To handle this, copy the list of sessions before iterating through them.
+ For extra safety, make sessions WeakPtr.
+
+ Add routines for the case of filtering with a predicate taking a const session.
+ In that case, we do not copy the vector but iterate through it as a small optimization.
+
+ Test: webrtc/concurrentVideoPlayback.html
+
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager):
+ (WebCore::HTMLMediaElement::hasMediaStreamSource const):
+ * html/HTMLMediaElement.h:
+ * platform/audio/PlatformMediaSession.cpp:
+ (WebCore::PlatformMediaSession::activeAudioSessionRequired const):
+ (WebCore::PlatformMediaSession::canPlayConcurrently const):
+ (WebCore::PlatformMediaSession::activeAudioSessionRequired): Deleted.
+ * platform/audio/PlatformMediaSession.h:
+ (WebCore::PlatformMediaSessionClient::hasMediaStreamSource const):
+ * platform/audio/PlatformMediaSessionManager.cpp:
+ (WebCore::PlatformMediaSessionManager::has const):
+ (WebCore::PlatformMediaSessionManager::activeAudioSessionRequired const):
+ (WebCore::PlatformMediaSessionManager::canProduceAudio const):
+ (WebCore::PlatformMediaSessionManager::count const):
+ (WebCore::PlatformMediaSessionManager::beginInterruption):
+ (WebCore::PlatformMediaSessionManager::endInterruption):
+ (WebCore::PlatformMediaSessionManager::addSession):
+ (WebCore::PlatformMediaSessionManager::removeSession):
+ (WebCore::PlatformMediaSessionManager::sessionWillBeginPlayback):
+ (WebCore::PlatformMediaSessionManager::sessionWillEndPlayback):
+ (WebCore::PlatformMediaSessionManager::setCurrentSession):
+ (WebCore::PlatformMediaSessionManager::currentSession const):
+ (WebCore::PlatformMediaSessionManager::applicationWillBecomeInactive):
+ (WebCore::PlatformMediaSessionManager::applicationDidBecomeActive):
+ (WebCore::PlatformMediaSessionManager::applicationDidEnterBackground):
+ (WebCore::PlatformMediaSessionManager::applicationWillEnterForeground):
+ (WebCore::PlatformMediaSessionManager::systemWillSleep):
+ (WebCore::PlatformMediaSessionManager::systemDidWake):
+ (WebCore::PlatformMediaSessionManager::stopAllMediaPlaybackForDocument):
+ (WebCore::PlatformMediaSessionManager::stopAllMediaPlaybackForProcess):
+ (WebCore::PlatformMediaSessionManager::suspendAllMediaPlaybackForDocument):
+ (WebCore::PlatformMediaSessionManager::resumeAllMediaPlaybackForDocument):
+ (WebCore::PlatformMediaSessionManager::suspendAllMediaBufferingForDocument):
+ (WebCore::PlatformMediaSessionManager::resumeAllMediaBufferingForDocument):
+ (WebCore::PlatformMediaSessionManager::currentSessionsMatching const):
+ (WebCore::PlatformMediaSessionManager::forEachMatchingSession):
+ (WebCore::PlatformMediaSessionManager::forEachMatchingSession const):
+ (WebCore::PlatformMediaSessionManager::forEachSession):
+ (WebCore::PlatformMediaSessionManager::anyOfSessions const):
+ (): Deleted.
+ (WebCore::PlatformMediaSessionManager::applicationWillBecomeInactive const): Deleted.
+ (WebCore::PlatformMediaSessionManager::applicationDidBecomeActive const): Deleted.
+ (WebCore::PlatformMediaSessionManager::applicationDidEnterBackground const): Deleted.
+ (WebCore::PlatformMediaSessionManager::applicationWillEnterForeground const): Deleted.
+ (WebCore::PlatformMediaSessionManager::forEachSession const): Deleted.
+ (WebCore::PlatformMediaSessionManager::findSession const): Deleted.
+ * platform/audio/PlatformMediaSessionManager.h:
+ (WebCore::PlatformMediaSessionManager::anyOfSessions const): Deleted.
+ * platform/audio/cocoa/MediaSessionManagerCocoa.mm:
+ (MediaSessionManagerCocoa::updateSessionState):
+ (MediaSessionManagerCocoa::beginInterruption):
+ * platform/audio/ios/MediaSessionManagerIOS.mm:
+ (WebCore::MediaSessionManageriOS::configureWireLessTargetMonitoring):
+ (WebCore::MediaSessionManageriOS::externalOutputDeviceAvailableDidChange):
+
2019-05-23 Saam barati <[email protected]>
[WHLSL] Add a helper for in-place AST mutation
Modified: trunk/Source/WebCore/dom/Document.cpp (245711 => 245712)
--- trunk/Source/WebCore/dom/Document.cpp 2019-05-23 20:44:06 UTC (rev 245711)
+++ trunk/Source/WebCore/dom/Document.cpp 2019-05-23 20:56:56 UTC (rev 245712)
@@ -1694,7 +1694,7 @@
void Document::stopAllMediaPlayback()
{
if (auto* platformMediaSessionManager = PlatformMediaSessionManager::sharedManagerIfExists())
- platformMediaSessionManager->stopAllMediaPlaybackForDocument(this);
+ platformMediaSessionManager->stopAllMediaPlaybackForDocument(*this);
}
void Document::suspendAllMediaPlayback()
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (245711 => 245712)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2019-05-23 20:44:06 UTC (rev 245711)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2019-05-23 20:56:56 UTC (rev 245712)
@@ -657,19 +657,17 @@
}
RefPtr<HTMLMediaElement> HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose purpose)
{
- auto allSessions = PlatformMediaSessionManager::sharedManager().currentSessionsMatching([] (const PlatformMediaSession& session) {
- return is<MediaElementSession>(session);
- });
-
Vector<MediaElementSessionInfo> candidateSessions;
bool atLeastOneNonCandidateMayBeConfusedForMainContent = false;
- for (auto& session : allSessions) {
- auto mediaElementSessionInfo = mediaElementSessionInfoForSession(downcast<MediaElementSession>(*session), purpose);
+ PlatformMediaSessionManager::sharedManager().forEachMatchingSession([](auto& session) {
+ return is<MediaElementSession>(session);
+ }, [&](auto& session) {
+ auto mediaElementSessionInfo = mediaElementSessionInfoForSession(downcast<MediaElementSession>(session), purpose);
if (mediaElementSessionInfo.canShowControlsManager)
candidateSessions.append(mediaElementSessionInfo);
else if (mediaSessionMayBeConfusedWithMainContent(mediaElementSessionInfo, purpose))
atLeastOneNonCandidateMayBeConfusedForMainContent = true;
- }
+ });
if (!candidateSessions.size())
return nullptr;
@@ -8137,6 +8135,15 @@
return m_bufferingPolicy;
}
+bool HTMLMediaElement::hasMediaStreamSource() const
+{
+#if ENABLE(MEDIA_STREAM)
+ return hasMediaStreamSrcObject();
+#else
+ return false;
+#endif
}
+}
+
#endif
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (245711 => 245712)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2019-05-23 20:44:06 UTC (rev 245711)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2019-05-23 20:56:56 UTC (rev 245712)
@@ -892,6 +892,7 @@
bool shouldOverrideBackgroundLoadingRestriction() const override;
bool canProduceAudio() const final;
bool processingUserGestureForMedia() const final;
+ bool hasMediaStreamSource() const final;
void pageMutedStateDidChange() override;
Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp (245711 => 245712)
--- trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp 2019-05-23 20:44:06 UTC (rev 245711)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp 2019-05-23 20:56:56 UTC (rev 245712)
@@ -342,7 +342,7 @@
return m_client.displayType();
}
-bool PlatformMediaSession::activeAudioSessionRequired()
+bool PlatformMediaSession::activeAudioSessionRequired() const
{
if (mediaType() == PlatformMediaSession::None)
return false;
@@ -388,6 +388,11 @@
PlatformMediaSessionManager::sharedManager().clientCharacteristicsChanged(*this);
}
+bool PlatformMediaSession::canPlayConcurrently(const PlatformMediaSession& otherSession) const
+{
+ return m_client.hasMediaStreamSource() && otherSession.m_client.hasMediaStreamSource();
+}
+
#if !RELEASE_LOG_DISABLED
WTFLogChannel& PlatformMediaSession::logChannel() const
{
Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSession.h (245711 => 245712)
--- trunk/Source/WebCore/platform/audio/PlatformMediaSession.h 2019-05-23 20:44:06 UTC (rev 245711)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSession.h 2019-05-23 20:56:56 UTC (rev 245712)
@@ -29,6 +29,7 @@
#include "Timer.h"
#include <wtf/LoggerHelper.h>
#include <wtf/Noncopyable.h>
+#include <wtf/WeakPtr.h>
#include <wtf/text/WTFString.h>
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
@@ -42,8 +43,9 @@
class PlatformMediaSessionClient;
class PlatformMediaSession
+ : public CanMakeWeakPtr<PlatformMediaSession>
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
- : public MediaPlaybackTargetClient
+ , public MediaPlaybackTargetClient
#endif
#if !RELEASE_LOG_DISABLED
, private LoggerHelper
@@ -170,7 +172,7 @@
virtual bool requiresPlaybackTargetRouteMonitoring() const { return false; }
#endif
- bool activeAudioSessionRequired();
+ bool activeAudioSessionRequired() const;
bool canProduceAudio() const;
void canProduceAudioChanged();
@@ -189,6 +191,8 @@
WTFLogChannel& logChannel() const final;
#endif
+ bool canPlayConcurrently(const PlatformMediaSession&) const;
+
protected:
PlatformMediaSessionClient& client() const { return m_client; }
@@ -253,6 +257,8 @@
virtual bool processingUserGestureForMedia() const = 0;
+ virtual bool hasMediaStreamSource() const { return false; }
+
protected:
virtual ~PlatformMediaSessionClient() = default;
};
Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (245711 => 245712)
--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp 2019-05-23 20:44:06 UTC (rev 245711)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp 2019-05-23 20:56:56 UTC (rev 245712)
@@ -79,7 +79,7 @@
{
ASSERT(type >= PlatformMediaSession::None && type <= PlatformMediaSession::MediaStreamCapturingAudio);
- return anyOfSessions([type] (PlatformMediaSession& session, size_t) {
+ return anyOfSessions([type] (auto& session) {
return session.mediaType() == type;
});
}
@@ -86,7 +86,7 @@
bool PlatformMediaSessionManager::activeAudioSessionRequired() const
{
- return anyOfSessions([] (PlatformMediaSession& session, size_t) {
+ return anyOfSessions([] (auto& session) {
return session.activeAudioSessionRequired();
});
}
@@ -93,7 +93,7 @@
bool PlatformMediaSessionManager::canProduceAudio() const
{
- return anyOfSessions([] (PlatformMediaSession& session, size_t) {
+ return anyOfSessions([] (auto& session) {
return session.canProduceAudio();
});
}
@@ -103,7 +103,7 @@
ASSERT(type >= PlatformMediaSession::None && type <= PlatformMediaSession::MediaStreamCapturingAudio);
int count = 0;
- for (auto* session : m_sessions) {
+ for (const auto& session : m_sessions) {
if (session->mediaType() == type)
++count;
}
@@ -116,7 +116,7 @@
ALWAYS_LOG(LOGIDENTIFIER);
m_interrupted = true;
- forEachSession([type] (PlatformMediaSession& session, size_t) {
+ forEachSession([type] (auto& session) {
session.beginInterruption(type);
});
updateSessionState();
@@ -127,7 +127,7 @@
ALWAYS_LOG(LOGIDENTIFIER);
m_interrupted = false;
- forEachSession([flags] (PlatformMediaSession& session, size_t) {
+ forEachSession([flags] (auto& session) {
session.endInterruption(flags);
});
}
@@ -135,8 +135,7 @@
void PlatformMediaSessionManager::addSession(PlatformMediaSession& session)
{
ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier());
-
- m_sessions.append(&session);
+ m_sessions.append(makeWeakPtr(session));
if (m_interrupted)
session.setState(PlatformMediaSession::Interrupted);
@@ -156,15 +155,12 @@
void PlatformMediaSessionManager::removeSession(PlatformMediaSession& session)
{
ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier());
-
+
size_t index = m_sessions.find(&session);
if (index == notFound)
return;
- if (m_iteratingOverSessions)
- m_sessions.at(index) = nullptr;
- else
- m_sessions.remove(index);
+ m_sessions.remove(index);
if (m_sessions.isEmpty() || std::all_of(m_sessions.begin(), m_sessions.end(), std::logical_not<void>())) {
m_remoteCommandListener = nullptr;
@@ -233,15 +229,16 @@
if (m_interrupted)
endInterruption(PlatformMediaSession::NoFlags);
- forEachSession([&] (PlatformMediaSession& oneSession, size_t) {
- if (&_oneSession_ == &session)
- return;
- if (oneSession.mediaType() == sessionType
- && restrictions & ConcurrentPlaybackNotPermitted
- && oneSession.state() == PlatformMediaSession::Playing)
+ if (restrictions & ConcurrentPlaybackNotPermitted) {
+ forEachMatchingSession([&session, sessionType](auto& oneSession) {
+ return &oneSession != &session
+ && oneSession.mediaType() == sessionType
+ && oneSession.state() == PlatformMediaSession::Playing
+ && !oneSession.canPlayConcurrently(session);
+ }, [](auto& oneSession) {
oneSession.pauseSession();
- });
-
+ });
+ }
ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier(), " returning true");
return true;
}
@@ -255,25 +252,27 @@
size_t pausingSessionIndex = notFound;
size_t lastPlayingSessionIndex = notFound;
- anyOfSessions([&] (PlatformMediaSession& oneSession, size_t i) {
+ for (size_t i = 0, size = m_sessions.size(); i < size; ++i) {
+ const auto& _oneSession_ = *m_sessions[i];
if (&_oneSession_ == &session) {
pausingSessionIndex = i;
- return false;
+ break;
}
if (oneSession.state() == PlatformMediaSession::Playing) {
lastPlayingSessionIndex = i;
- return false;
+ break;
}
- return oneSession.state() != PlatformMediaSession::Playing;
- });
+ if (oneSession.state() != PlatformMediaSession::Playing)
+ break;
+ }
if (lastPlayingSessionIndex == notFound || pausingSessionIndex == notFound)
return;
if (pausingSessionIndex > lastPlayingSessionIndex)
return;
-
+
m_sessions.remove(pausingSessionIndex);
- m_sessions.insert(lastPlayingSessionIndex, &session);
+ m_sessions.append(makeWeakPtr(session));
ALWAYS_LOG(LOGIDENTIFIER, "session moved from index ", pausingSessionIndex, " to ", lastPlayingSessionIndex);
}
@@ -296,7 +295,7 @@
return;
m_sessions.remove(index);
- m_sessions.insert(0, &session);
+ m_sessions.insert(0, makeWeakPtr(session));
if (m_remoteCommandListener)
m_remoteCommandListener->updateSupportedCommands();
@@ -308,40 +307,32 @@
if (!m_sessions.size())
return nullptr;
- return m_sessions[0];
+ return m_sessions[0].get();
}
-Vector<PlatformMediaSession*> PlatformMediaSessionManager::currentSessionsMatching(const WTF::Function<bool(const PlatformMediaSession&)>& filter)
+void PlatformMediaSessionManager::applicationWillBecomeInactive()
{
- Vector<PlatformMediaSession*> matchingSessions;
- forEachSession([&] (PlatformMediaSession& session, size_t) {
- if (filter(session))
- matchingSessions.append(&session);
- });
- return matchingSessions;
-}
-
-void PlatformMediaSessionManager::applicationWillBecomeInactive() const
-{
ALWAYS_LOG(LOGIDENTIFIER);
- forEachSession([&] (PlatformMediaSession& session, size_t) {
- if (m_restrictions[session.mediaType()] & InactiveProcessPlaybackRestricted)
- session.beginInterruption(PlatformMediaSession::ProcessInactive);
+ forEachMatchingSession([&](auto& session) {
+ return m_restrictions[session.mediaType()] & InactiveProcessPlaybackRestricted;
+ }, [](auto& session) {
+ session.beginInterruption(PlatformMediaSession::ProcessInactive);
});
}
-void PlatformMediaSessionManager::applicationDidBecomeActive() const
+void PlatformMediaSessionManager::applicationDidBecomeActive()
{
ALWAYS_LOG(LOGIDENTIFIER);
- forEachSession([&] (PlatformMediaSession& session, size_t) {
- if (m_restrictions[session.mediaType()] & InactiveProcessPlaybackRestricted)
- session.endInterruption(PlatformMediaSession::MayResumePlaying);
+ forEachMatchingSession([&](auto& session) {
+ return m_restrictions[session.mediaType()] & InactiveProcessPlaybackRestricted;
+ }, [](auto& session) {
+ session.endInterruption(PlatformMediaSession::MayResumePlaying);
});
}
-void PlatformMediaSessionManager::applicationDidEnterBackground(bool suspendedUnderLock) const
+void PlatformMediaSessionManager::applicationDidEnterBackground(bool suspendedUnderLock)
{
ALWAYS_LOG(LOGIDENTIFIER, "suspendedUnderLock: ", suspendedUnderLock);
@@ -350,7 +341,7 @@
m_isApplicationInBackground = true;
- forEachSession([&] (PlatformMediaSession& session, size_t) {
+ forEachSession([&] (auto& session) {
if (suspendedUnderLock && m_restrictions[session.mediaType()] & SuspendedUnderLockPlaybackRestricted)
session.beginInterruption(PlatformMediaSession::SuspendedUnderLock);
else if (m_restrictions[session.mediaType()] & BackgroundProcessPlaybackRestricted)
@@ -358,7 +349,7 @@
});
}
-void PlatformMediaSessionManager::applicationWillEnterForeground(bool suspendedUnderLock) const
+void PlatformMediaSessionManager::applicationWillEnterForeground(bool suspendedUnderLock)
{
ALWAYS_LOG(LOGIDENTIFIER, "suspendedUnderLock: ", suspendedUnderLock);
@@ -367,9 +358,10 @@
m_isApplicationInBackground = false;
- forEachSession([&] (PlatformMediaSession& session, size_t) {
- if ((suspendedUnderLock && m_restrictions[session.mediaType()] & SuspendedUnderLockPlaybackRestricted) || m_restrictions[session.mediaType()] & BackgroundProcessPlaybackRestricted)
- session.endInterruption(PlatformMediaSession::MayResumePlaying);
+ forEachMatchingSession([&](auto& session) {
+ return (suspendedUnderLock && m_restrictions[session.mediaType()] & SuspendedUnderLockPlaybackRestricted) || m_restrictions[session.mediaType()] & BackgroundProcessPlaybackRestricted;
+ }, [](auto& session) {
+ session.endInterruption(PlatformMediaSession::MayResumePlaying);
});
}
@@ -438,7 +430,7 @@
if (m_interrupted)
return;
- forEachSession([] (PlatformMediaSession& session, size_t) {
+ forEachSession([] (auto& session) {
session.beginInterruption(PlatformMediaSession::SystemSleep);
});
}
@@ -448,7 +440,7 @@
if (m_interrupted)
return;
- forEachSession([] (PlatformMediaSession& session, size_t) {
+ forEachSession([] (auto& session) {
session.endInterruption(PlatformMediaSession::MayResumePlaying);
});
}
@@ -458,17 +450,16 @@
updateSessionState();
}
-void PlatformMediaSessionManager::stopAllMediaPlaybackForDocument(const Document* document)
+void PlatformMediaSessionManager::stopAllMediaPlaybackForDocument(const Document& document)
{
- forEachSession([document] (PlatformMediaSession& session, size_t) {
- if (session.client().hostingDocument() == document)
- session.pauseSession();
+ forEachDocumentSession(document, [](auto& session) {
+ session.pauseSession();
});
}
void PlatformMediaSessionManager::stopAllMediaPlaybackForProcess()
{
- forEachSession([] (PlatformMediaSession& session, size_t) {
+ forEachSession([] (auto& session) {
session.stopSession();
});
}
@@ -475,74 +466,75 @@
void PlatformMediaSessionManager::suspendAllMediaPlaybackForDocument(const Document& document)
{
- forEachSession([&] (PlatformMediaSession& session, size_t) {
- if (session.client().hostingDocument() == &document)
- session.beginInterruption(PlatformMediaSession::PlaybackSuspended);
+ forEachDocumentSession(document, [](auto& session) {
+ session.beginInterruption(PlatformMediaSession::PlaybackSuspended);
});
}
void PlatformMediaSessionManager::resumeAllMediaPlaybackForDocument(const Document& document)
{
- forEachSession([&] (PlatformMediaSession& session, size_t) {
- if (session.client().hostingDocument() == &document)
- session.endInterruption(PlatformMediaSession::MayResumePlaying);
+ forEachDocumentSession(document, [](auto& session) {
+ session.endInterruption(PlatformMediaSession::MayResumePlaying);
});
}
void PlatformMediaSessionManager::suspendAllMediaBufferingForDocument(const Document& document)
{
- forEachSession([&] (PlatformMediaSession& session, size_t) {
- if (session.client().hostingDocument() == &document)
- session.suspendBuffering();
+ forEachDocumentSession(document, [](auto& session) {
+ session.suspendBuffering();
});
}
void PlatformMediaSessionManager::resumeAllMediaBufferingForDocument(const Document& document)
{
- forEachSession([&] (PlatformMediaSession& session, size_t) {
- if (session.client().hostingDocument() == &document)
- session.resumeBuffering();
+ forEachDocumentSession(document, [](auto& session) {
+ session.resumeBuffering();
});
}
-void PlatformMediaSessionManager::forEachSession(const Function<void(PlatformMediaSession&, size_t)>& predicate) const
+Vector<WeakPtr<PlatformMediaSession>> PlatformMediaSessionManager::sessionsMatching(const WTF::Function<bool(const PlatformMediaSession&)>& filter) const
{
- ++m_iteratingOverSessions;
+ Vector<WeakPtr<PlatformMediaSession>> matchingSessions;
+ for (auto& session : m_sessions) {
+ if (filter(*session))
+ matchingSessions.append(session);
+ }
+ return matchingSessions;
+}
- for (size_t i = 0, size = m_sessions.size(); i < size; ++i) {
- auto session = m_sessions[i];
- if (!session)
- continue;
- predicate(*session, i);
+void PlatformMediaSessionManager::forEachMatchingSession(const Function<bool(const PlatformMediaSession&)>& predicate, const Function<void(PlatformMediaSession&)>& callback)
+{
+ for (auto& session : sessionsMatching(predicate)) {
+ ASSERT(session);
+ if (session)
+ callback(*session);
}
+}
- --m_iteratingOverSessions;
- if (!m_iteratingOverSessions)
- m_sessions.removeAll(nullptr);
+void PlatformMediaSessionManager::forEachDocumentSession(const Document& document, const Function<void(PlatformMediaSession&)>& callback)
+{
+ forEachMatchingSession([&document](auto& session) {
+ return session.client().hostingDocument() == &document;
+ }, [&callback](auto& session) {
+ callback(session);
+ });
}
-PlatformMediaSession* PlatformMediaSessionManager::findSession(const Function<bool(PlatformMediaSession&, size_t)>& predicate) const
+void PlatformMediaSessionManager::forEachSession(const Function<void(PlatformMediaSession&)>& callback)
{
- ++m_iteratingOverSessions;
-
- PlatformMediaSession* foundSession = nullptr;
- for (size_t i = 0, size = m_sessions.size(); i < size; ++i) {
- auto session = m_sessions[i];
- if (!session)
- continue;
-
- if (!predicate(*session, i))
- continue;
-
- foundSession = session;
- break;
+ auto sessions = m_sessions;
+ for (auto& session : sessions) {
+ ASSERT(session);
+ if (session)
+ callback(*session);
}
+}
- --m_iteratingOverSessions;
- if (!m_iteratingOverSessions)
- m_sessions.removeAll(nullptr);
-
- return foundSession;
+bool PlatformMediaSessionManager::anyOfSessions(const Function<bool(const PlatformMediaSession&)>& predicate) const
+{
+ return WTF::anyOf(m_sessions, [&predicate](const auto& session) {
+ return predicate(*session);
+ });
}
static bool& deactivateAudioSession()
Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h (245711 => 245712)
--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h 2019-05-23 20:44:06 UTC (rev 245711)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h 2019-05-23 20:56:56 UTC (rev 245712)
@@ -81,14 +81,14 @@
WEBCORE_EXPORT virtual void beginInterruption(PlatformMediaSession::InterruptionType);
WEBCORE_EXPORT void endInterruption(PlatformMediaSession::EndInterruptionFlags);
- WEBCORE_EXPORT void applicationWillBecomeInactive() const;
- WEBCORE_EXPORT void applicationDidBecomeActive() const;
- WEBCORE_EXPORT void applicationWillEnterForeground(bool suspendedUnderLock) const;
- WEBCORE_EXPORT void applicationDidEnterBackground(bool suspendedUnderLock) const;
+ WEBCORE_EXPORT void applicationWillBecomeInactive();
+ WEBCORE_EXPORT void applicationDidBecomeActive();
+ WEBCORE_EXPORT void applicationWillEnterForeground(bool suspendedUnderLock);
+ WEBCORE_EXPORT void applicationDidEnterBackground(bool suspendedUnderLock);
WEBCORE_EXPORT void processWillSuspend();
WEBCORE_EXPORT void processDidResume();
- void stopAllMediaPlaybackForDocument(const Document*);
+ void stopAllMediaPlaybackForDocument(const Document&);
WEBCORE_EXPORT void stopAllMediaPlaybackForProcess();
void suspendAllMediaPlaybackForDocument(const Document&);
@@ -127,10 +127,10 @@
void setCurrentSession(PlatformMediaSession&);
PlatformMediaSession* currentSession() const;
- Vector<PlatformMediaSession*> currentSessionsMatching(const WTF::Function<bool(const PlatformMediaSession&)>&);
-
void sessionIsPlayingToWirelessPlaybackTargetChanged(PlatformMediaSession&);
+ void forEachMatchingSession(const Function<bool(const PlatformMediaSession&)>& predicate, const Function<void(PlatformMediaSession&)>& matchingCallback);
+
protected:
friend class PlatformMediaSession;
explicit PlatformMediaSessionManager();
@@ -138,9 +138,9 @@
void addSession(PlatformMediaSession&);
virtual void removeSession(PlatformMediaSession&);
- void forEachSession(const Function<void(PlatformMediaSession&, size_t)>&) const;
- PlatformMediaSession* findSession(const Function<bool(PlatformMediaSession&, size_t)>&) const;
- bool anyOfSessions(const Function<bool(PlatformMediaSession&, size_t)>& predicate) const { return findSession(predicate); }
+ void forEachSession(const Function<void(PlatformMediaSession&)>&);
+ void forEachDocumentSession(const Document&, const Function<void(PlatformMediaSession&)>&);
+ bool anyOfSessions(const Function<bool(const PlatformMediaSession&)>&) const;
AudioHardwareListener* audioHardwareListener() { return m_audioHardwareListener.get(); }
@@ -171,8 +171,10 @@
void systemWillSleep() override;
void systemDidWake() override;
+ Vector<WeakPtr<PlatformMediaSession>> sessionsMatching(const Function<bool(const PlatformMediaSession&)>&) const;
+
SessionRestrictions m_restrictions[PlatformMediaSession::MediaStreamCapturingAudio + 1];
- mutable Vector<PlatformMediaSession*> m_sessions;
+ mutable Vector<WeakPtr<PlatformMediaSession>> m_sessions;
std::unique_ptr<RemoteCommandListener> m_remoteCommandListener;
std::unique_ptr<PAL::SystemSleepListener> m_systemSleepListener;
RefPtr<AudioHardwareListener> m_audioHardwareListener;
@@ -185,7 +187,6 @@
bool m_interrupted { false };
mutable bool m_isApplicationInBackground { false };
bool m_willIgnoreSystemInterruptions { false };
- mutable int m_iteratingOverSessions { 0 };
bool m_processIsSuspended { false };
#if USE(AUDIO_SESSION)
Modified: trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm (245711 => 245712)
--- trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm 2019-05-23 20:44:06 UTC (rev 245711)
+++ trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm 2019-05-23 20:56:56 UTC (rev 245712)
@@ -97,7 +97,7 @@
return;
bool hasAudibleAudioOrVideoMediaType = false;
- forEachSession([&hasAudibleAudioOrVideoMediaType] (PlatformMediaSession& session, size_t) mutable {
+ forEachSession([&hasAudibleAudioOrVideoMediaType] (auto& session) mutable {
auto type = session.mediaType();
if ((type == PlatformMediaSession::VideoAudio || type == PlatformMediaSession::Audio) && session.canProduceAudio() && session.hasPlayedSinceLastInterruption())
hasAudibleAudioOrVideoMediaType = true;
@@ -122,7 +122,7 @@
void MediaSessionManagerCocoa::beginInterruption(PlatformMediaSession::InterruptionType type)
{
if (type == PlatformMediaSession::InterruptionType::SystemInterruption) {
- forEachSession([] (PlatformMediaSession& session, size_t) {
+ forEachSession([] (auto& session) {
session.clearHasPlayedSinceLastInterruption();
});
}
Modified: trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm (245711 => 245712)
--- trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm 2019-05-23 20:44:06 UTC (rev 245711)
+++ trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm 2019-05-23 20:56:56 UTC (rev 245712)
@@ -146,7 +146,7 @@
void MediaSessionManageriOS::configureWireLessTargetMonitoring()
{
#if HAVE(MEDIA_PLAYER) && !PLATFORM(WATCHOS)
- bool requiresMonitoring = anyOfSessions([] (PlatformMediaSession& session, size_t) {
+ bool requiresMonitoring = anyOfSessions([] (auto& session) {
return session.requiresPlaybackTargetRouteMonitoring();
});
@@ -187,7 +187,7 @@
bool haveTargets = [m_objcObserver hasWirelessTargetsAvailable];
ALWAYS_LOG(LOGIDENTIFIER, haveTargets);
- forEachSession([haveTargets] (PlatformMediaSession& session, size_t) {
+ forEachSession([haveTargets] (auto& session) {
session.externalOutputDeviceAvailableDidChange(haveTargets);
});