⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 245712 in webkit


Ignore:
Timestamp:
May 23, 2019, 1:56:56 PM (7 years ago)
Author:
youenn@apple.com
Message:

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.

Source/WebCore:

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):

LayoutTests:

  • webrtc/concurrentVideoPlayback-expected.txt: Added.
  • webrtc/concurrentVideoPlayback.html: Added.
Location:
trunk
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r245711 r245712  
     12019-05-23  Youenn Fablet  <youenn@apple.com>
     2
     3        Multiple videos (with audios) with autoplay & playinline not working. Only one video play at a time.
     4        https://bugs.webkit.org/show_bug.cgi?id=193312
     5        <rdar://problem/47189864>
     6
     7        Reviewed by Jer Noble.
     8
     9        * webrtc/concurrentVideoPlayback-expected.txt: Added.
     10        * webrtc/concurrentVideoPlayback.html: Added.
     11
    1122019-05-23  Shawn Roberts  <sroberts@apple.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r245706 r245712  
     12019-05-23  Youenn Fablet  <youenn@apple.com>
     2
     3        Multiple videos (with audios) with autoplay & playinline not working. Only one video play at a time.
     4        https://bugs.webkit.org/show_bug.cgi?id=193312
     5        <rdar://problem/47189864>
     6
     7        Reviewed by Jer Noble.
     8
     9        Allow all MediaStream backed video elements to play together.
     10        Any non MediaStream backed video will stop all MediaStream backed video elements.
     11        Conversely, all non MediaStream backed videos will stop when playing one MediaStream backed video.
     12
     13        Refactor PlatformMediaSessionManager as the way to iterate through sessions
     14        is not safe when pausing a session: if playing, the session will be moved in the array of sessions.
     15
     16        To handle this, copy the list of sessions before iterating through them.
     17        For extra safety, make sessions WeakPtr.
     18
     19        Add routines for the case of filtering with a predicate taking a const session.
     20        In that case, we do not copy the vector but iterate through it as a small optimization.
     21
     22        Test: webrtc/concurrentVideoPlayback.html
     23
     24        * html/HTMLMediaElement.cpp:
     25        (WebCore::HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager):
     26        (WebCore::HTMLMediaElement::hasMediaStreamSource const):
     27        * html/HTMLMediaElement.h:
     28        * platform/audio/PlatformMediaSession.cpp:
     29        (WebCore::PlatformMediaSession::activeAudioSessionRequired const):
     30        (WebCore::PlatformMediaSession::canPlayConcurrently const):
     31        (WebCore::PlatformMediaSession::activeAudioSessionRequired): Deleted.
     32        * platform/audio/PlatformMediaSession.h:
     33        (WebCore::PlatformMediaSessionClient::hasMediaStreamSource const):
     34        * platform/audio/PlatformMediaSessionManager.cpp:
     35        (WebCore::PlatformMediaSessionManager::has const):
     36        (WebCore::PlatformMediaSessionManager::activeAudioSessionRequired const):
     37        (WebCore::PlatformMediaSessionManager::canProduceAudio const):
     38        (WebCore::PlatformMediaSessionManager::count const):
     39        (WebCore::PlatformMediaSessionManager::beginInterruption):
     40        (WebCore::PlatformMediaSessionManager::endInterruption):
     41        (WebCore::PlatformMediaSessionManager::addSession):
     42        (WebCore::PlatformMediaSessionManager::removeSession):
     43        (WebCore::PlatformMediaSessionManager::sessionWillBeginPlayback):
     44        (WebCore::PlatformMediaSessionManager::sessionWillEndPlayback):
     45        (WebCore::PlatformMediaSessionManager::setCurrentSession):
     46        (WebCore::PlatformMediaSessionManager::currentSession const):
     47        (WebCore::PlatformMediaSessionManager::applicationWillBecomeInactive):
     48        (WebCore::PlatformMediaSessionManager::applicationDidBecomeActive):
     49        (WebCore::PlatformMediaSessionManager::applicationDidEnterBackground):
     50        (WebCore::PlatformMediaSessionManager::applicationWillEnterForeground):
     51        (WebCore::PlatformMediaSessionManager::systemWillSleep):
     52        (WebCore::PlatformMediaSessionManager::systemDidWake):
     53        (WebCore::PlatformMediaSessionManager::stopAllMediaPlaybackForDocument):
     54        (WebCore::PlatformMediaSessionManager::stopAllMediaPlaybackForProcess):
     55        (WebCore::PlatformMediaSessionManager::suspendAllMediaPlaybackForDocument):
     56        (WebCore::PlatformMediaSessionManager::resumeAllMediaPlaybackForDocument):
     57        (WebCore::PlatformMediaSessionManager::suspendAllMediaBufferingForDocument):
     58        (WebCore::PlatformMediaSessionManager::resumeAllMediaBufferingForDocument):
     59        (WebCore::PlatformMediaSessionManager::currentSessionsMatching const):
     60        (WebCore::PlatformMediaSessionManager::forEachMatchingSession):
     61        (WebCore::PlatformMediaSessionManager::forEachMatchingSession const):
     62        (WebCore::PlatformMediaSessionManager::forEachSession):
     63        (WebCore::PlatformMediaSessionManager::anyOfSessions const):
     64        (): Deleted.
     65        (WebCore::PlatformMediaSessionManager::applicationWillBecomeInactive const): Deleted.
     66        (WebCore::PlatformMediaSessionManager::applicationDidBecomeActive const): Deleted.
     67        (WebCore::PlatformMediaSessionManager::applicationDidEnterBackground const): Deleted.
     68        (WebCore::PlatformMediaSessionManager::applicationWillEnterForeground const): Deleted.
     69        (WebCore::PlatformMediaSessionManager::forEachSession const): Deleted.
     70        (WebCore::PlatformMediaSessionManager::findSession const): Deleted.
     71        * platform/audio/PlatformMediaSessionManager.h:
     72        (WebCore::PlatformMediaSessionManager::anyOfSessions const): Deleted.
     73        * platform/audio/cocoa/MediaSessionManagerCocoa.mm:
     74        (MediaSessionManagerCocoa::updateSessionState):
     75        (MediaSessionManagerCocoa::beginInterruption):
     76        * platform/audio/ios/MediaSessionManagerIOS.mm:
     77        (WebCore::MediaSessionManageriOS::configureWireLessTargetMonitoring):
     78        (WebCore::MediaSessionManageriOS::externalOutputDeviceAvailableDidChange):
     79
    1802019-05-23  Saam barati  <sbarati@apple.com>
    281
  • trunk/Source/WebCore/dom/Document.cpp

    r245642 r245712  
    16951695{
    16961696    if (auto* platformMediaSessionManager = PlatformMediaSessionManager::sharedManagerIfExists())
    1697         platformMediaSessionManager->stopAllMediaPlaybackForDocument(this);
     1697        platformMediaSessionManager->stopAllMediaPlaybackForDocument(*this);
    16981698}
    16991699
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r245508 r245712  
    658658RefPtr<HTMLMediaElement> HTMLMediaElement::bestMediaElementForShowingPlaybackControlsManager(MediaElementSession::PlaybackControlsPurpose purpose)
    659659{
    660     auto allSessions = PlatformMediaSessionManager::sharedManager().currentSessionsMatching([] (const PlatformMediaSession& session) {
    661         return is<MediaElementSession>(session);
    662     });
    663 
    664660    Vector<MediaElementSessionInfo> candidateSessions;
    665661    bool atLeastOneNonCandidateMayBeConfusedForMainContent = false;
    666     for (auto& session : allSessions) {
    667         auto mediaElementSessionInfo = mediaElementSessionInfoForSession(downcast<MediaElementSession>(*session), purpose);
     662    PlatformMediaSessionManager::sharedManager().forEachMatchingSession([](auto& session) {
     663        return is<MediaElementSession>(session);
     664    }, [&](auto& session) {
     665        auto mediaElementSessionInfo = mediaElementSessionInfoForSession(downcast<MediaElementSession>(session), purpose);
    668666        if (mediaElementSessionInfo.canShowControlsManager)
    669667            candidateSessions.append(mediaElementSessionInfo);
    670668        else if (mediaSessionMayBeConfusedWithMainContent(mediaElementSessionInfo, purpose))
    671669            atLeastOneNonCandidateMayBeConfusedForMainContent = true;
    672     }
     670    });
    673671
    674672    if (!candidateSessions.size())
     
    81388136}
    81398137
    8140 }
    8141 
    8142 #endif
     8138bool HTMLMediaElement::hasMediaStreamSource() const
     8139{
     8140#if ENABLE(MEDIA_STREAM)
     8141    return hasMediaStreamSrcObject();
     8142#else
     8143    return false;
     8144#endif
     8145}
     8146
     8147}
     8148
     8149#endif
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r245467 r245712  
    893893    bool canProduceAudio() const final;
    894894    bool processingUserGestureForMedia() const final;
     895    bool hasMediaStreamSource() const final;
    895896
    896897    void pageMutedStateDidChange() override;
  • trunk/Source/WebCore/platform/audio/PlatformMediaSession.cpp

    r243033 r245712  
    343343}
    344344
    345 bool PlatformMediaSession::activeAudioSessionRequired()
     345bool PlatformMediaSession::activeAudioSessionRequired() const
    346346{
    347347    if (mediaType() == PlatformMediaSession::None)
     
    389389}
    390390
     391bool PlatformMediaSession::canPlayConcurrently(const PlatformMediaSession& otherSession) const
     392{
     393    return m_client.hasMediaStreamSource() && otherSession.m_client.hasMediaStreamSource();
     394}
     395
    391396#if !RELEASE_LOG_DISABLED
    392397WTFLogChannel& PlatformMediaSession::logChannel() const
  • trunk/Source/WebCore/platform/audio/PlatformMediaSession.h

    r243033 r245712  
    3030#include <wtf/LoggerHelper.h>
    3131#include <wtf/Noncopyable.h>
     32#include <wtf/WeakPtr.h>
    3233#include <wtf/text/WTFString.h>
    3334
     
    4344
    4445class PlatformMediaSession
     46    : public CanMakeWeakPtr<PlatformMediaSession>
    4547#if ENABLE(WIRELESS_PLAYBACK_TARGET)
    46     : public MediaPlaybackTargetClient
     48    , public MediaPlaybackTargetClient
    4749#endif
    4850#if !RELEASE_LOG_DISABLED
     
    171173#endif
    172174
    173     bool activeAudioSessionRequired();
     175    bool activeAudioSessionRequired() const;
    174176    bool canProduceAudio() const;
    175177    void canProduceAudioChanged();
     
    189191    WTFLogChannel& logChannel() const final;
    190192#endif
     193
     194    bool canPlayConcurrently(const PlatformMediaSession&) const;
    191195
    192196protected:
     
    254258    virtual bool processingUserGestureForMedia() const = 0;
    255259
     260    virtual bool hasMediaStreamSource() const { return false; }
     261
    256262protected:
    257263    virtual ~PlatformMediaSessionClient() = default;
  • trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp

    r244490 r245712  
    8080    ASSERT(type >= PlatformMediaSession::None && type <= PlatformMediaSession::MediaStreamCapturingAudio);
    8181
    82     return anyOfSessions([type] (PlatformMediaSession& session, size_t) {
     82    return anyOfSessions([type] (auto& session) {
    8383        return session.mediaType() == type;
    8484    });
     
    8787bool PlatformMediaSessionManager::activeAudioSessionRequired() const
    8888{
    89     return anyOfSessions([] (PlatformMediaSession& session, size_t) {
     89    return anyOfSessions([] (auto& session) {
    9090        return session.activeAudioSessionRequired();
    9191    });
     
    9494bool PlatformMediaSessionManager::canProduceAudio() const
    9595{
    96     return anyOfSessions([] (PlatformMediaSession& session, size_t) {
     96    return anyOfSessions([] (auto& session) {
    9797        return session.canProduceAudio();
    9898    });
     
    104104
    105105    int count = 0;
    106     for (auto* session : m_sessions) {
     106    for (const auto& session : m_sessions) {
    107107        if (session->mediaType() == type)
    108108            ++count;
     
    117117
    118118    m_interrupted = true;
    119     forEachSession([type] (PlatformMediaSession& session, size_t) {
     119    forEachSession([type] (auto& session) {
    120120        session.beginInterruption(type);
    121121    });
     
    128128
    129129    m_interrupted = false;
    130     forEachSession([flags] (PlatformMediaSession& session, size_t) {
     130    forEachSession([flags] (auto& session) {
    131131        session.endInterruption(flags);
    132132    });
     
    136136{
    137137    ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier());
    138    
    139     m_sessions.append(&session);
     138    m_sessions.append(makeWeakPtr(session));
    140139    if (m_interrupted)
    141140        session.setState(PlatformMediaSession::Interrupted);
     
    157156{
    158157    ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier());
    159    
     158
    160159    size_t index = m_sessions.find(&session);
    161160    if (index == notFound)
    162161        return;
    163162
    164     if (m_iteratingOverSessions)
    165         m_sessions.at(index) = nullptr;
    166     else
    167         m_sessions.remove(index);
     163    m_sessions.remove(index);
    168164
    169165    if (m_sessions.isEmpty() || std::all_of(m_sessions.begin(), m_sessions.end(), std::logical_not<void>())) {
     
    234230        endInterruption(PlatformMediaSession::NoFlags);
    235231
    236     forEachSession([&] (PlatformMediaSession& oneSession, size_t) {
    237         if (&oneSession == &session)
    238             return;
    239         if (oneSession.mediaType() == sessionType
    240             && restrictions & ConcurrentPlaybackNotPermitted
    241             && oneSession.state() == PlatformMediaSession::Playing)
     232    if (restrictions & ConcurrentPlaybackNotPermitted) {
     233        forEachMatchingSession([&session, sessionType](auto& oneSession) {
     234            return &oneSession != &session
     235                && oneSession.mediaType() == sessionType
     236                && oneSession.state() == PlatformMediaSession::Playing
     237                && !oneSession.canPlayConcurrently(session);
     238        }, [](auto& oneSession) {
    242239            oneSession.pauseSession();
    243     });
    244 
     240        });
     241    }
    245242    ALWAYS_LOG(LOGIDENTIFIER, session.logIdentifier(), " returning true");
    246243    return true;
     
    256253    size_t pausingSessionIndex = notFound;
    257254    size_t lastPlayingSessionIndex = notFound;
    258     anyOfSessions([&] (PlatformMediaSession& oneSession, size_t i) {
     255    for (size_t i = 0, size = m_sessions.size(); i < size; ++i) {
     256        const auto& oneSession = *m_sessions[i];
    259257        if (&oneSession == &session) {
    260258            pausingSessionIndex = i;
    261             return false;
     259            break;
    262260        }
    263261        if (oneSession.state() == PlatformMediaSession::Playing) {
    264262            lastPlayingSessionIndex = i;
    265             return false;
     263            break;
    266264        }
    267         return oneSession.state() != PlatformMediaSession::Playing;
    268     });
     265        if (oneSession.state() != PlatformMediaSession::Playing)
     266            break;
     267    }
    269268    if (lastPlayingSessionIndex == notFound || pausingSessionIndex == notFound)
    270269        return;
     
    272271    if (pausingSessionIndex > lastPlayingSessionIndex)
    273272        return;
    274    
     273
    275274    m_sessions.remove(pausingSessionIndex);
    276     m_sessions.insert(lastPlayingSessionIndex, &session);
     275    m_sessions.append(makeWeakPtr(session));
    277276   
    278277    ALWAYS_LOG(LOGIDENTIFIER, "session moved from index ", pausingSessionIndex, " to ", lastPlayingSessionIndex);
     
    297296
    298297    m_sessions.remove(index);
    299     m_sessions.insert(0, &session);
     298    m_sessions.insert(0, makeWeakPtr(session));
    300299    if (m_remoteCommandListener)
    301300        m_remoteCommandListener->updateSupportedCommands();
     
    309308        return nullptr;
    310309
    311     return m_sessions[0];
    312 }
    313 
    314 Vector<PlatformMediaSession*> PlatformMediaSessionManager::currentSessionsMatching(const WTF::Function<bool(const PlatformMediaSession&)>& filter)
    315 {
    316     Vector<PlatformMediaSession*> matchingSessions;
    317     forEachSession([&] (PlatformMediaSession& session, size_t) {
    318         if (filter(session))
    319             matchingSessions.append(&session);
    320     });
    321     return matchingSessions;
    322 }
    323 
    324 void PlatformMediaSessionManager::applicationWillBecomeInactive() const
     310    return m_sessions[0].get();
     311}
     312
     313void PlatformMediaSessionManager::applicationWillBecomeInactive()
    325314{
    326315    ALWAYS_LOG(LOGIDENTIFIER);
    327316
    328     forEachSession([&] (PlatformMediaSession& session, size_t) {
    329         if (m_restrictions[session.mediaType()] & InactiveProcessPlaybackRestricted)
    330             session.beginInterruption(PlatformMediaSession::ProcessInactive);
    331     });
    332 }
    333 
    334 void PlatformMediaSessionManager::applicationDidBecomeActive() const
     317    forEachMatchingSession([&](auto& session) {
     318        return m_restrictions[session.mediaType()] & InactiveProcessPlaybackRestricted;
     319    }, [](auto& session) {
     320        session.beginInterruption(PlatformMediaSession::ProcessInactive);
     321    });
     322}
     323
     324void PlatformMediaSessionManager::applicationDidBecomeActive()
    335325{
    336326    ALWAYS_LOG(LOGIDENTIFIER);
    337327
    338     forEachSession([&] (PlatformMediaSession& session, size_t) {
    339         if (m_restrictions[session.mediaType()] & InactiveProcessPlaybackRestricted)
    340             session.endInterruption(PlatformMediaSession::MayResumePlaying);
    341     });
    342 }
    343 
    344 void PlatformMediaSessionManager::applicationDidEnterBackground(bool suspendedUnderLock) const
     328    forEachMatchingSession([&](auto& session) {
     329        return m_restrictions[session.mediaType()] & InactiveProcessPlaybackRestricted;
     330    }, [](auto& session) {
     331        session.endInterruption(PlatformMediaSession::MayResumePlaying);
     332    });
     333}
     334
     335void PlatformMediaSessionManager::applicationDidEnterBackground(bool suspendedUnderLock)
    345336{
    346337    ALWAYS_LOG(LOGIDENTIFIER, "suspendedUnderLock: ", suspendedUnderLock);
     
    351342    m_isApplicationInBackground = true;
    352343
    353     forEachSession([&] (PlatformMediaSession& session, size_t) {
     344    forEachSession([&] (auto& session) {
    354345        if (suspendedUnderLock && m_restrictions[session.mediaType()] & SuspendedUnderLockPlaybackRestricted)
    355346            session.beginInterruption(PlatformMediaSession::SuspendedUnderLock);
     
    359350}
    360351
    361 void PlatformMediaSessionManager::applicationWillEnterForeground(bool suspendedUnderLock) const
     352void PlatformMediaSessionManager::applicationWillEnterForeground(bool suspendedUnderLock)
    362353{
    363354    ALWAYS_LOG(LOGIDENTIFIER, "suspendedUnderLock: ", suspendedUnderLock);
     
    368359    m_isApplicationInBackground = false;
    369360
    370     forEachSession([&] (PlatformMediaSession& session, size_t) {
    371         if ((suspendedUnderLock && m_restrictions[session.mediaType()] & SuspendedUnderLockPlaybackRestricted) || m_restrictions[session.mediaType()] & BackgroundProcessPlaybackRestricted)
    372             session.endInterruption(PlatformMediaSession::MayResumePlaying);
     361    forEachMatchingSession([&](auto& session) {
     362        return (suspendedUnderLock && m_restrictions[session.mediaType()] & SuspendedUnderLockPlaybackRestricted) || m_restrictions[session.mediaType()] & BackgroundProcessPlaybackRestricted;
     363    }, [](auto& session) {
     364        session.endInterruption(PlatformMediaSession::MayResumePlaying);
    373365    });
    374366}
     
    439431        return;
    440432
    441     forEachSession([] (PlatformMediaSession& session, size_t) {
     433    forEachSession([] (auto& session) {
    442434        session.beginInterruption(PlatformMediaSession::SystemSleep);
    443435    });
     
    449441        return;
    450442
    451     forEachSession([] (PlatformMediaSession& session, size_t) {
     443    forEachSession([] (auto& session) {
    452444        session.endInterruption(PlatformMediaSession::MayResumePlaying);
    453445    });
     
    459451}
    460452
    461 void PlatformMediaSessionManager::stopAllMediaPlaybackForDocument(const Document* document)
    462 {
    463     forEachSession([document] (PlatformMediaSession& session, size_t) {
    464         if (session.client().hostingDocument() == document)
    465             session.pauseSession();
     453void PlatformMediaSessionManager::stopAllMediaPlaybackForDocument(const Document& document)
     454{
     455    forEachDocumentSession(document, [](auto& session) {
     456        session.pauseSession();
    466457    });
    467458}
     
    469460void PlatformMediaSessionManager::stopAllMediaPlaybackForProcess()
    470461{
    471     forEachSession([] (PlatformMediaSession& session, size_t) {
     462    forEachSession([] (auto& session) {
    472463        session.stopSession();
    473464    });
     
    476467void PlatformMediaSessionManager::suspendAllMediaPlaybackForDocument(const Document& document)
    477468{
    478     forEachSession([&] (PlatformMediaSession& session, size_t) {
    479         if (session.client().hostingDocument() == &document)
    480             session.beginInterruption(PlatformMediaSession::PlaybackSuspended);
     469    forEachDocumentSession(document, [](auto& session) {
     470        session.beginInterruption(PlatformMediaSession::PlaybackSuspended);
    481471    });
    482472}
     
    484474void PlatformMediaSessionManager::resumeAllMediaPlaybackForDocument(const Document& document)
    485475{
    486     forEachSession([&] (PlatformMediaSession& session, size_t) {
    487         if (session.client().hostingDocument() == &document)
    488             session.endInterruption(PlatformMediaSession::MayResumePlaying);
     476    forEachDocumentSession(document, [](auto& session) {
     477        session.endInterruption(PlatformMediaSession::MayResumePlaying);
    489478    });
    490479}
     
    492481void PlatformMediaSessionManager::suspendAllMediaBufferingForDocument(const Document& document)
    493482{
    494     forEachSession([&] (PlatformMediaSession& session, size_t) {
    495         if (session.client().hostingDocument() == &document)
    496             session.suspendBuffering();
     483    forEachDocumentSession(document, [](auto& session) {
     484        session.suspendBuffering();
    497485    });
    498486}
     
    500488void PlatformMediaSessionManager::resumeAllMediaBufferingForDocument(const Document& document)
    501489{
    502     forEachSession([&] (PlatformMediaSession& session, size_t) {
    503         if (session.client().hostingDocument() == &document)
    504             session.resumeBuffering();
    505     });
    506 }
    507 
    508 void PlatformMediaSessionManager::forEachSession(const Function<void(PlatformMediaSession&, size_t)>& predicate) const
    509 {
    510     ++m_iteratingOverSessions;
    511 
    512     for (size_t i = 0, size = m_sessions.size(); i < size; ++i) {
    513         auto session = m_sessions[i];
    514         if (!session)
    515             continue;
    516         predicate(*session, i);
    517     }
    518 
    519     --m_iteratingOverSessions;
    520     if (!m_iteratingOverSessions)
    521         m_sessions.removeAll(nullptr);
    522 }
    523 
    524 PlatformMediaSession* PlatformMediaSessionManager::findSession(const Function<bool(PlatformMediaSession&, size_t)>& predicate) const
    525 {
    526     ++m_iteratingOverSessions;
    527 
    528     PlatformMediaSession* foundSession = nullptr;
    529     for (size_t i = 0, size = m_sessions.size(); i < size; ++i) {
    530         auto session = m_sessions[i];
    531         if (!session)
    532             continue;
    533 
    534         if (!predicate(*session, i))
    535             continue;
    536 
    537         foundSession = session;
    538         break;
    539     }
    540 
    541     --m_iteratingOverSessions;
    542     if (!m_iteratingOverSessions)
    543         m_sessions.removeAll(nullptr);
    544 
    545     return foundSession;
     490    forEachDocumentSession(document, [](auto& session) {
     491        session.resumeBuffering();
     492    });
     493}
     494
     495Vector<WeakPtr<PlatformMediaSession>> PlatformMediaSessionManager::sessionsMatching(const WTF::Function<bool(const PlatformMediaSession&)>& filter) const
     496{
     497    Vector<WeakPtr<PlatformMediaSession>> matchingSessions;
     498    for (auto& session : m_sessions) {
     499        if (filter(*session))
     500            matchingSessions.append(session);
     501    }
     502    return matchingSessions;
     503}
     504
     505void PlatformMediaSessionManager::forEachMatchingSession(const Function<bool(const PlatformMediaSession&)>& predicate, const Function<void(PlatformMediaSession&)>& callback)
     506{
     507    for (auto& session : sessionsMatching(predicate)) {
     508        ASSERT(session);
     509        if (session)
     510            callback(*session);
     511    }
     512}
     513
     514void PlatformMediaSessionManager::forEachDocumentSession(const Document& document, const Function<void(PlatformMediaSession&)>& callback)
     515{
     516    forEachMatchingSession([&document](auto& session) {
     517        return session.client().hostingDocument() == &document;
     518    }, [&callback](auto& session) {
     519        callback(session);
     520    });
     521}
     522
     523void PlatformMediaSessionManager::forEachSession(const Function<void(PlatformMediaSession&)>& callback)
     524{
     525    auto sessions = m_sessions;
     526    for (auto& session : sessions) {
     527        ASSERT(session);
     528        if (session)
     529            callback(*session);
     530    }
     531}
     532
     533bool PlatformMediaSessionManager::anyOfSessions(const Function<bool(const PlatformMediaSession&)>& predicate) const
     534{
     535    return WTF::anyOf(m_sessions, [&predicate](const auto& session) {
     536        return predicate(*session);
     537    });
    546538}
    547539
  • trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h

    r245199 r245712  
    8282    WEBCORE_EXPORT void endInterruption(PlatformMediaSession::EndInterruptionFlags);
    8383
    84     WEBCORE_EXPORT void applicationWillBecomeInactive() const;
    85     WEBCORE_EXPORT void applicationDidBecomeActive() const;
    86     WEBCORE_EXPORT void applicationWillEnterForeground(bool suspendedUnderLock) const;
    87     WEBCORE_EXPORT void applicationDidEnterBackground(bool suspendedUnderLock) const;
     84    WEBCORE_EXPORT void applicationWillBecomeInactive();
     85    WEBCORE_EXPORT void applicationDidBecomeActive();
     86    WEBCORE_EXPORT void applicationWillEnterForeground(bool suspendedUnderLock);
     87    WEBCORE_EXPORT void applicationDidEnterBackground(bool suspendedUnderLock);
    8888    WEBCORE_EXPORT void processWillSuspend();
    8989    WEBCORE_EXPORT void processDidResume();
    9090
    91     void stopAllMediaPlaybackForDocument(const Document*);
     91    void stopAllMediaPlaybackForDocument(const Document&);
    9292    WEBCORE_EXPORT void stopAllMediaPlaybackForProcess();
    9393
     
    128128    PlatformMediaSession* currentSession() const;
    129129
    130     Vector<PlatformMediaSession*> currentSessionsMatching(const WTF::Function<bool(const PlatformMediaSession&)>&);
    131 
    132130    void sessionIsPlayingToWirelessPlaybackTargetChanged(PlatformMediaSession&);
     131
     132    void forEachMatchingSession(const Function<bool(const PlatformMediaSession&)>& predicate, const Function<void(PlatformMediaSession&)>& matchingCallback);
    133133
    134134protected:
     
    139139    virtual void removeSession(PlatformMediaSession&);
    140140
    141     void forEachSession(const Function<void(PlatformMediaSession&, size_t)>&) const;
    142     PlatformMediaSession* findSession(const Function<bool(PlatformMediaSession&, size_t)>&) const;
    143     bool anyOfSessions(const Function<bool(PlatformMediaSession&, size_t)>& predicate) const { return findSession(predicate); }
     141    void forEachSession(const Function<void(PlatformMediaSession&)>&);
     142    void forEachDocumentSession(const Document&, const Function<void(PlatformMediaSession&)>&);
     143    bool anyOfSessions(const Function<bool(const PlatformMediaSession&)>&) const;
    144144
    145145    AudioHardwareListener* audioHardwareListener() { return m_audioHardwareListener.get(); }
     
    172172    void systemDidWake() override;
    173173
     174    Vector<WeakPtr<PlatformMediaSession>> sessionsMatching(const Function<bool(const PlatformMediaSession&)>&) const;
     175
    174176    SessionRestrictions m_restrictions[PlatformMediaSession::MediaStreamCapturingAudio + 1];
    175     mutable Vector<PlatformMediaSession*> m_sessions;
     177    mutable Vector<WeakPtr<PlatformMediaSession>> m_sessions;
    176178    std::unique_ptr<RemoteCommandListener> m_remoteCommandListener;
    177179    std::unique_ptr<PAL::SystemSleepListener> m_systemSleepListener;
     
    186188    mutable bool m_isApplicationInBackground { false };
    187189    bool m_willIgnoreSystemInterruptions { false };
    188     mutable int m_iteratingOverSessions { 0 };
    189190    bool m_processIsSuspended { false };
    190191
  • trunk/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm

    r245156 r245712  
    9898
    9999    bool hasAudibleAudioOrVideoMediaType = false;
    100     forEachSession([&hasAudibleAudioOrVideoMediaType] (PlatformMediaSession& session, size_t) mutable {
     100    forEachSession([&hasAudibleAudioOrVideoMediaType] (auto& session) mutable {
    101101        auto type = session.mediaType();
    102102        if ((type == PlatformMediaSession::VideoAudio || type == PlatformMediaSession::Audio) && session.canProduceAudio() && session.hasPlayedSinceLastInterruption())
     
    123123{
    124124    if (type == PlatformMediaSession::InterruptionType::SystemInterruption) {
    125         forEachSession([] (PlatformMediaSession& session, size_t) {
     125        forEachSession([] (auto& session) {
    126126            session.clearHasPlayedSinceLastInterruption();
    127127        });
  • trunk/Source/WebCore/platform/audio/ios/MediaSessionManagerIOS.mm

    r245236 r245712  
    147147{
    148148#if HAVE(MEDIA_PLAYER) && !PLATFORM(WATCHOS)
    149     bool requiresMonitoring = anyOfSessions([] (PlatformMediaSession& session, size_t) {
     149    bool requiresMonitoring = anyOfSessions([] (auto& session) {
    150150        return session.requiresPlaybackTargetRouteMonitoring();
    151151    });
     
    188188    ALWAYS_LOG(LOGIDENTIFIER, haveTargets);
    189189
    190     forEachSession([haveTargets] (PlatformMediaSession& session, size_t) {
     190    forEachSession([haveTargets] (auto& session) {
    191191        session.externalOutputDeviceAvailableDidChange(haveTargets);
    192192    });
Note: See TracChangeset for help on using the changeset viewer.