Title: [293078] branches/safari-613-branch
Revision
293078
Author
[email protected]
Date
2022-04-19 22:39:01 -0700 (Tue, 19 Apr 2022)

Log Message

Cherry-pick r291759. rdar://problem/89589891

    [iOS] WebKit app is sometimes not "Now Playing" during initial playback
    https://bugs.webkit.org/show_bug.cgi?id=236993
    <rdar://88827167>

    Reviewed by Eric Carlson.

    Source/WebCore:

    Test: media/audio-session-category-at-most-recent-playback.html

    Recently, we have added the concept of "preparingToPlay" to PlatformMediaSession to allow
    the correct category to be set if updateSessionState() is called after playback is allowed
    by the MediaSessionManager, but before playback is actually started by the media element.
    However, this depends on updateSessionState() being called synchronously during playback.
    We disabled this synchronous update in r269077 due to the large runtime cost when a large
    number of media elements are created (but not used) at once.

    Relax this asynchronous update in the case where the state is moving to "Playing", which
    ensures that the correct AudioSessionCategory is set before playback starts, rather than
    immediately afterward.

    To support testing that the category was correctly set before playback started, add an
    ivar to HTMLMediaElement that is set to the current AudioSessionCategory immediately before
    the media element instructs the MediaPlayer to start playback. Expose this ivar to Internals.

    Drive-by fixes: AudioSession::CategoryType cannot be forward declared, as it is a public
    member of a class. Allow the enum to be forward declared by moving the declaration outside
    the class, but allow current uses of the enum to continue by typedefing it inside the class
    to the original enum name. Add an IDL enumeration matching the AudioSession one in Interals.idl
    and convert the existing audioSessionCategory() call to use the new enumeration.

    (Unforunately in the case where USE_AUDIO_SESSION is not set, the enumeration must be re-
    declared. This can be removed and the entire implementation wrapped in a USE() check, once
    the bindings generator is extended to allow "Conditional="-style attributes for USE checks.)

    The added test is flakey due to a previous change which would keep the MediaSession category
    in "MediaPlayback" for up to 2s after playback ends. To counteract this flakiness, reset the
    state of the PlatformMediaSessionManager between tests.

    * html/HTMLMediaElement.cpp:
    (WebCore::m_categoryAtMostRecentPlayback):
    (WebCore::HTMLMediaElement::playPlayer):
    (WebCore::m_logIdentifier): Deleted.
    * html/HTMLMediaElement.h:
    (WebCore::HTMLMediaElement::categoryAtMostRecentPlayback const):
    * platform/audio/AudioSession.h:
    * platform/audio/PlatformMediaSessionManager.cpp:
    (WebCore::PlatformMediaSessionManager::sessionStateChanged):
    * platform/audio/PlatformMediaSessionManager.h:
    (WebCore::PlatformMediaSessionManager::resetSessionState):
    * platform/audio/cocoa/MediaSessionManagerCocoa.h:
    * platform/audio/cocoa/MediaSessionManagerCocoa.mm:
    (WebCore::MediaSessionManagerCocoa::resetSessionState):
    * testing/Internals.cpp:
    (WebCore::Internals::resetToConsistentState):
    * testing/Internals.cpp:
    (WebCore::Internals::audioSessionCategory const):
    (WebCore::Internals::categoryAtMostRecentPlayback const):
    * testing/Internals.h:
    * testing/Internals.idl:

    LayoutTests:

    Fix the audio-session-category test. Creating the oscilator actually does change the
    AudioSession category to "Ambient", but (previously) only in the next run loop, so a
    synchronous test that the AudioSession category is "None" succeeds. Now that starting
    playback (as happens when creating an audio node) changes the AudioSession synchronously,
    the test begins failing.

    * media/audio-session-category-at-most-recent-playback-expected.txt: Added.
    * media/audio-session-category-at-most-recent-playback.html: Added.
    * media/audio-session-category-expected.txt:
    * media/audio-session-category.html:

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291759 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Added Paths

Diff

Modified: branches/safari-613-branch/LayoutTests/ChangeLog (293077 => 293078)


--- branches/safari-613-branch/LayoutTests/ChangeLog	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/LayoutTests/ChangeLog	2022-04-20 05:39:01 UTC (rev 293078)
@@ -1,5 +1,104 @@
 2022-04-19  Alan Coon  <[email protected]>
 
+        Cherry-pick r291759. rdar://problem/89589891
+
+    [iOS] WebKit app is sometimes not "Now Playing" during initial playback
+    https://bugs.webkit.org/show_bug.cgi?id=236993
+    <rdar://88827167>
+    
+    Reviewed by Eric Carlson.
+    
+    Source/WebCore:
+    
+    Test: media/audio-session-category-at-most-recent-playback.html
+    
+    Recently, we have added the concept of "preparingToPlay" to PlatformMediaSession to allow
+    the correct category to be set if updateSessionState() is called after playback is allowed
+    by the MediaSessionManager, but before playback is actually started by the media element.
+    However, this depends on updateSessionState() being called synchronously during playback.
+    We disabled this synchronous update in r269077 due to the large runtime cost when a large
+    number of media elements are created (but not used) at once.
+    
+    Relax this asynchronous update in the case where the state is moving to "Playing", which
+    ensures that the correct AudioSessionCategory is set before playback starts, rather than
+    immediately afterward.
+    
+    To support testing that the category was correctly set before playback started, add an
+    ivar to HTMLMediaElement that is set to the current AudioSessionCategory immediately before
+    the media element instructs the MediaPlayer to start playback. Expose this ivar to Internals.
+    
+    Drive-by fixes: AudioSession::CategoryType cannot be forward declared, as it is a public
+    member of a class. Allow the enum to be forward declared by moving the declaration outside
+    the class, but allow current uses of the enum to continue by typedefing it inside the class
+    to the original enum name. Add an IDL enumeration matching the AudioSession one in Interals.idl
+    and convert the existing audioSessionCategory() call to use the new enumeration.
+    
+    (Unforunately in the case where USE_AUDIO_SESSION is not set, the enumeration must be re-
+    declared. This can be removed and the entire implementation wrapped in a USE() check, once
+    the bindings generator is extended to allow "Conditional="-style attributes for USE checks.)
+    
+    The added test is flakey due to a previous change which would keep the MediaSession category
+    in "MediaPlayback" for up to 2s after playback ends. To counteract this flakiness, reset the
+    state of the PlatformMediaSessionManager between tests.
+    
+    * html/HTMLMediaElement.cpp:
+    (WebCore::m_categoryAtMostRecentPlayback):
+    (WebCore::HTMLMediaElement::playPlayer):
+    (WebCore::m_logIdentifier): Deleted.
+    * html/HTMLMediaElement.h:
+    (WebCore::HTMLMediaElement::categoryAtMostRecentPlayback const):
+    * platform/audio/AudioSession.h:
+    * platform/audio/PlatformMediaSessionManager.cpp:
+    (WebCore::PlatformMediaSessionManager::sessionStateChanged):
+    * platform/audio/PlatformMediaSessionManager.h:
+    (WebCore::PlatformMediaSessionManager::resetSessionState):
+    * platform/audio/cocoa/MediaSessionManagerCocoa.h:
+    * platform/audio/cocoa/MediaSessionManagerCocoa.mm:
+    (WebCore::MediaSessionManagerCocoa::resetSessionState):
+    * testing/Internals.cpp:
+    (WebCore::Internals::resetToConsistentState):
+    * testing/Internals.cpp:
+    (WebCore::Internals::audioSessionCategory const):
+    (WebCore::Internals::categoryAtMostRecentPlayback const):
+    * testing/Internals.h:
+    * testing/Internals.idl:
+    
+    LayoutTests:
+    
+    Fix the audio-session-category test. Creating the oscilator actually does change the
+    AudioSession category to "Ambient", but (previously) only in the next run loop, so a
+    synchronous test that the AudioSession category is "None" succeeds. Now that starting
+    playback (as happens when creating an audio node) changes the AudioSession synchronously,
+    the test begins failing.
+    
+    * media/audio-session-category-at-most-recent-playback-expected.txt: Added.
+    * media/audio-session-category-at-most-recent-playback.html: Added.
+    * media/audio-session-category-expected.txt:
+    * media/audio-session-category.html:
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291759 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-03-23  Jer Noble  <[email protected]>
+
+            [iOS] WebKit app is sometimes not "Now Playing" during initial playback
+            https://bugs.webkit.org/show_bug.cgi?id=236993
+            <rdar://88827167>
+
+            Reviewed by Eric Carlson.
+
+            Fix the audio-session-category test. Creating the oscilator actually does change the
+            AudioSession category to "Ambient", but (previously) only in the next run loop, so a
+            synchronous test that the AudioSession category is "None" succeeds. Now that starting
+            playback (as happens when creating an audio node) changes the AudioSession synchronously,
+            the test begins failing.
+
+            * media/audio-session-category-at-most-recent-playback-expected.txt: Added.
+            * media/audio-session-category-at-most-recent-playback.html: Added.
+            * media/audio-session-category-expected.txt:
+            * media/audio-session-category.html:
+
+2022-04-19  Alan Coon  <[email protected]>
+
         Cherry-pick r292049. rdar://problem/89104216
 
     [macOS] Muted video is sometimes paused when entering fullscreen

Added: branches/safari-613-branch/LayoutTests/media/audio-session-category-at-most-recent-playback-expected.txt (0 => 293078)


--- branches/safari-613-branch/LayoutTests/media/audio-session-category-at-most-recent-playback-expected.txt	                        (rev 0)
+++ branches/safari-613-branch/LayoutTests/media/audio-session-category-at-most-recent-playback-expected.txt	2022-04-20 05:39:01 UTC (rev 293078)
@@ -0,0 +1,16 @@
+
+RUN(video.muted = true)
+RUN(video.src = "" "content/audio-tracks"))
+EVENT(canplaythrough)
+EXPECTED (internals.categoryAtMostRecentPlayback(video) == 'None') OK
+RUN(video.play())
+EVENT(playing)
+EXPECTED (internals.categoryAtMostRecentPlayback(video) == 'None') OK
+RUN(video.pause())
+EVENT(pause)
+RUN(video.muted = false)
+RUN(video.play())
+EVENT(playing)
+EXPECTED (internals.categoryAtMostRecentPlayback(video) == 'MediaPlayback') OK
+END OF TEST
+

Added: branches/safari-613-branch/LayoutTests/media/audio-session-category-at-most-recent-playback.html (0 => 293078)


--- branches/safari-613-branch/LayoutTests/media/audio-session-category-at-most-recent-playback.html	                        (rev 0)
+++ branches/safari-613-branch/LayoutTests/media/audio-session-category-at-most-recent-playback.html	2022-04-20 05:39:01 UTC (rev 293078)
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src=""
+    <script src=""
+    <script>
+    window.addEventListener('load', async event => {
+        findMediaElement();
+
+        if (window.internals)
+            internals.settings.setShouldManageAudioSessionCategory(true);
+
+        run('video.muted = true');
+        run('video.src = "" "content/audio-tracks")');
+
+        await waitFor(video, 'canplaythrough');
+
+        testExpected('internals.categoryAtMostRecentPlayback(video)', 'None');
+
+        run('video.play()');
+        await waitFor(video, 'playing');
+        await sleepFor(500);
+
+        testExpected('internals.categoryAtMostRecentPlayback(video)', 'None');
+
+        run('video.pause()');
+        await waitFor(video, 'pause');
+
+        run('video.muted = false');
+        run('video.play()');
+        await waitFor(video, 'playing');
+        await sleepFor(500);
+        testExpected('internals.categoryAtMostRecentPlayback(video)', 'MediaPlayback');
+
+        endTest();
+    });
+    </script>
+</head>
+<body>
+    <video></video>
+</body>
+</html>
\ No newline at end of file

Modified: branches/safari-613-branch/LayoutTests/media/audio-session-category-expected.txt (293077 => 293078)


--- branches/safari-613-branch/LayoutTests/media/audio-session-category-expected.txt	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/LayoutTests/media/audio-session-category-expected.txt	2022-04-20 05:39:01 UTC (rev 293078)
@@ -34,7 +34,7 @@
 ** Check category before creating AudioContext.
 EXPECTED (internals.audioSessionCategory() == 'None') OK
 
-** Check category after oscillator graph has been connected but not started.
+** Check category after AudioContext has been created but not started.
 EXPECTED (internals.audioSessionCategory() == 'None') OK
 
 ** Check category after starting oscillator.

Modified: branches/safari-613-branch/LayoutTests/media/audio-session-category.html (293077 => 293078)


--- branches/safari-613-branch/LayoutTests/media/audio-session-category.html	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/LayoutTests/media/audio-session-category.html	2022-04-20 05:39:01 UTC (rev 293078)
@@ -58,11 +58,12 @@
             consoleWrite('<br><br>** AudioContext test **');
             await waitForCategory('None', 10, '<br>** Check category before creating AudioContext.');
 
-            consoleWrite('<br>** Check category after oscillator graph has been connected but not started.');
+            consoleWrite('<br>** Check category after AudioContext has been created but not started.');
             let context = new AudioContext();
+            testExpected('internals.audioSessionCategory()', 'None');
+
             let oscillator = null;
             let gainNode = context.createGain();
-
             oscillator = context.createOscillator();
             oscillator.type = 'square';
             oscillator.frequency.setValueAtTime(440, context.currentTime);
@@ -70,9 +71,9 @@
             oscillator.connect(gainNode);
             gainNode.connect(context.destination);
             gainNode.gain.value = 0.1
-            testExpected('internals.audioSessionCategory()', 'None');
 
             consoleWrite('<br>** Check category after starting oscillator.');
+            context.resume();
             oscillator.start(0);
             await sleepFor(500);
             testExpected('internals.audioSessionCategory()', 'AmbientSound');

Modified: branches/safari-613-branch/LayoutTests/platform/glib/TestExpectations (293077 => 293078)


--- branches/safari-613-branch/LayoutTests/platform/glib/TestExpectations	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/LayoutTests/platform/glib/TestExpectations	2022-04-20 05:39:01 UTC (rev 293078)
@@ -1704,6 +1704,9 @@
 # UNSUPPORTED tests. Things we must skip.
 #////////////////////////////////////////////////////////////////////////////////////////
 
+# Tests behavior specific to MediaSessionManagerCocoa
+media/audio-session-category-at-most-recent-playback.html [ Skip ]
+
 # This test assumes we cannot play RTSP, but we can.
 media/unsupported-rtsp.html [ WontFix Skip ]
 

Modified: branches/safari-613-branch/LayoutTests/platform/mac-wk1/TestExpectations (293077 => 293078)


--- branches/safari-613-branch/LayoutTests/platform/mac-wk1/TestExpectations	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/LayoutTests/platform/mac-wk1/TestExpectations	2022-04-20 05:39:01 UTC (rev 293078)
@@ -65,6 +65,7 @@
 http/tests/navigation/page-cache-getUserMedia-pending-promise.html [ Skip ]
 http/tests/navigation/page-cache-mediastream.html [ Skip ]
 media/audio-session-category.html [ Skip ]
+media/audio-session-category-at-most-recent-playback.html [ Skip ]
 
 http/wpt/mediarecorder [ Skip ]
 imported/w3c/web-platform-tests/mediacapture-record [ Skip ]

Modified: branches/safari-613-branch/Source/WebCore/ChangeLog (293077 => 293078)


--- branches/safari-613-branch/Source/WebCore/ChangeLog	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/Source/WebCore/ChangeLog	2022-04-20 05:39:01 UTC (rev 293078)
@@ -1,5 +1,146 @@
 2022-04-19  Alan Coon  <[email protected]>
 
+        Cherry-pick r291759. rdar://problem/89589891
+
+    [iOS] WebKit app is sometimes not "Now Playing" during initial playback
+    https://bugs.webkit.org/show_bug.cgi?id=236993
+    <rdar://88827167>
+    
+    Reviewed by Eric Carlson.
+    
+    Source/WebCore:
+    
+    Test: media/audio-session-category-at-most-recent-playback.html
+    
+    Recently, we have added the concept of "preparingToPlay" to PlatformMediaSession to allow
+    the correct category to be set if updateSessionState() is called after playback is allowed
+    by the MediaSessionManager, but before playback is actually started by the media element.
+    However, this depends on updateSessionState() being called synchronously during playback.
+    We disabled this synchronous update in r269077 due to the large runtime cost when a large
+    number of media elements are created (but not used) at once.
+    
+    Relax this asynchronous update in the case where the state is moving to "Playing", which
+    ensures that the correct AudioSessionCategory is set before playback starts, rather than
+    immediately afterward.
+    
+    To support testing that the category was correctly set before playback started, add an
+    ivar to HTMLMediaElement that is set to the current AudioSessionCategory immediately before
+    the media element instructs the MediaPlayer to start playback. Expose this ivar to Internals.
+    
+    Drive-by fixes: AudioSession::CategoryType cannot be forward declared, as it is a public
+    member of a class. Allow the enum to be forward declared by moving the declaration outside
+    the class, but allow current uses of the enum to continue by typedefing it inside the class
+    to the original enum name. Add an IDL enumeration matching the AudioSession one in Interals.idl
+    and convert the existing audioSessionCategory() call to use the new enumeration.
+    
+    (Unforunately in the case where USE_AUDIO_SESSION is not set, the enumeration must be re-
+    declared. This can be removed and the entire implementation wrapped in a USE() check, once
+    the bindings generator is extended to allow "Conditional="-style attributes for USE checks.)
+    
+    The added test is flakey due to a previous change which would keep the MediaSession category
+    in "MediaPlayback" for up to 2s after playback ends. To counteract this flakiness, reset the
+    state of the PlatformMediaSessionManager between tests.
+    
+    * html/HTMLMediaElement.cpp:
+    (WebCore::m_categoryAtMostRecentPlayback):
+    (WebCore::HTMLMediaElement::playPlayer):
+    (WebCore::m_logIdentifier): Deleted.
+    * html/HTMLMediaElement.h:
+    (WebCore::HTMLMediaElement::categoryAtMostRecentPlayback const):
+    * platform/audio/AudioSession.h:
+    * platform/audio/PlatformMediaSessionManager.cpp:
+    (WebCore::PlatformMediaSessionManager::sessionStateChanged):
+    * platform/audio/PlatformMediaSessionManager.h:
+    (WebCore::PlatformMediaSessionManager::resetSessionState):
+    * platform/audio/cocoa/MediaSessionManagerCocoa.h:
+    * platform/audio/cocoa/MediaSessionManagerCocoa.mm:
+    (WebCore::MediaSessionManagerCocoa::resetSessionState):
+    * testing/Internals.cpp:
+    (WebCore::Internals::resetToConsistentState):
+    * testing/Internals.cpp:
+    (WebCore::Internals::audioSessionCategory const):
+    (WebCore::Internals::categoryAtMostRecentPlayback const):
+    * testing/Internals.h:
+    * testing/Internals.idl:
+    
+    LayoutTests:
+    
+    Fix the audio-session-category test. Creating the oscilator actually does change the
+    AudioSession category to "Ambient", but (previously) only in the next run loop, so a
+    synchronous test that the AudioSession category is "None" succeeds. Now that starting
+    playback (as happens when creating an audio node) changes the AudioSession synchronously,
+    the test begins failing.
+    
+    * media/audio-session-category-at-most-recent-playback-expected.txt: Added.
+    * media/audio-session-category-at-most-recent-playback.html: Added.
+    * media/audio-session-category-expected.txt:
+    * media/audio-session-category.html:
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@291759 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-03-23  Jer Noble  <[email protected]>
+
+            [iOS] WebKit app is sometimes not "Now Playing" during initial playback
+            https://bugs.webkit.org/show_bug.cgi?id=236993
+            <rdar://88827167>
+
+            Reviewed by Eric Carlson.
+
+            Test: media/audio-session-category-at-most-recent-playback.html
+
+            Recently, we have added the concept of "preparingToPlay" to PlatformMediaSession to allow
+            the correct category to be set if updateSessionState() is called after playback is allowed
+            by the MediaSessionManager, but before playback is actually started by the media element.
+            However, this depends on updateSessionState() being called synchronously during playback.
+            We disabled this synchronous update in r269077 due to the large runtime cost when a large
+            number of media elements are created (but not used) at once.
+
+            Relax this asynchronous update in the case where the state is moving to "Playing", which
+            ensures that the correct AudioSessionCategory is set before playback starts, rather than
+            immediately afterward.
+
+            To support testing that the category was correctly set before playback started, add an
+            ivar to HTMLMediaElement that is set to the current AudioSessionCategory immediately before
+            the media element instructs the MediaPlayer to start playback. Expose this ivar to Internals.
+
+            Drive-by fixes: AudioSession::CategoryType cannot be forward declared, as it is a public
+            member of a class. Allow the enum to be forward declared by moving the declaration outside
+            the class, but allow current uses of the enum to continue by typedefing it inside the class
+            to the original enum name. Add an IDL enumeration matching the AudioSession one in Interals.idl
+            and convert the existing audioSessionCategory() call to use the new enumeration.
+
+            (Unforunately in the case where USE_AUDIO_SESSION is not set, the enumeration must be re-
+            declared. This can be removed and the entire implementation wrapped in a USE() check, once
+            the bindings generator is extended to allow "Conditional="-style attributes for USE checks.)
+
+            The added test is flakey due to a previous change which would keep the MediaSession category
+            in "MediaPlayback" for up to 2s after playback ends. To counteract this flakiness, reset the
+            state of the PlatformMediaSessionManager between tests.
+
+            * html/HTMLMediaElement.cpp:
+            (WebCore::m_categoryAtMostRecentPlayback):
+            (WebCore::HTMLMediaElement::playPlayer):
+            (WebCore::m_logIdentifier): Deleted.
+            * html/HTMLMediaElement.h:
+            (WebCore::HTMLMediaElement::categoryAtMostRecentPlayback const):
+            * platform/audio/AudioSession.h:
+            * platform/audio/PlatformMediaSessionManager.cpp:
+            (WebCore::PlatformMediaSessionManager::sessionStateChanged):
+            * platform/audio/PlatformMediaSessionManager.h:
+            (WebCore::PlatformMediaSessionManager::resetSessionState):
+            * platform/audio/cocoa/MediaSessionManagerCocoa.h:
+            * platform/audio/cocoa/MediaSessionManagerCocoa.mm:
+            (WebCore::MediaSessionManagerCocoa::resetSessionState):
+            * testing/Internals.cpp:
+            (WebCore::Internals::resetToConsistentState):
+            * testing/Internals.cpp:
+            (WebCore::Internals::audioSessionCategory const):
+            (WebCore::Internals::categoryAtMostRecentPlayback const):
+            * testing/Internals.h:
+            * testing/Internals.idl:
+
+2022-04-19  Alan Coon  <[email protected]>
+
         Cherry-pick r290997. rdar://problem/79950080
 
     [iOS] Flash media controls when a fullscreen video resets its source

Modified: branches/safari-613-branch/Source/WebCore/html/HTMLMediaElement.cpp (293077 => 293078)


--- branches/safari-613-branch/Source/WebCore/html/HTMLMediaElement.cpp	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/Source/WebCore/html/HTMLMediaElement.cpp	2022-04-20 05:39:01 UTC (rev 293078)
@@ -130,6 +130,10 @@
 #include <wtf/Ref.h>
 #include <wtf/text/CString.h>
 
+#if USE(AUDIO_SESSION)
+#include "AudioSession.h"
+#endif
+
 #if ENABLE(WEB_AUDIO)
 #include "AudioSourceProvider.h"
 #include "MediaElementAudioSourceNode.h"
@@ -458,6 +462,9 @@
     , m_logger(&document.logger())
     , m_logIdentifier(uniqueLogIdentifier())
 #endif
+#if USE(AUDIO_SESSION)
+    , m_categoryAtMostRecentPlayback(AudioSessionCategory::None)
+#endif
 {
     allMediaElements().add(this);
 
@@ -5675,6 +5682,10 @@
     if (!m_player)
         return;
 
+#if USE(AUDIO_SESSION)
+    m_categoryAtMostRecentPlayback = AudioSession::sharedSession().category();
+#endif
+
 #if ENABLE(MEDIA_SESSION) && ENABLE(MEDIA_SESSION_COORDINATOR)
     do {
         if (!m_player->supportsPlayAtHostTime())

Modified: branches/safari-613-branch/Source/WebCore/html/HTMLMediaElement.h (293077 => 293078)


--- branches/safari-613-branch/Source/WebCore/html/HTMLMediaElement.h	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/Source/WebCore/html/HTMLMediaElement.h	2022-04-20 05:39:01 UTC (rev 293078)
@@ -605,6 +605,9 @@
 
     void updateMediaPlayer(IntSize, bool);
     WEBCORE_EXPORT bool elementIsHidden() const;
+#if USE(AUDIO_SESSION)
+    WEBCORE_EXPORT AudioSessionCategory categoryAtMostRecentPlayback() const { return m_categoryAtMostRecentPlayback; }
+#endif
 
 protected:
     HTMLMediaElement(const QualifiedName&, Document&, bool createdByParser);
@@ -1233,6 +1236,10 @@
     String m_audioOutputHashedDeviceId;
 #endif
     String m_id;
+
+#if USE(AUDIO_SESSION)
+    AudioSessionCategory m_categoryAtMostRecentPlayback;
+#endif
 };
 
 String convertEnumerationToString(HTMLMediaElement::AutoplayEventPlaybackState);

Modified: branches/safari-613-branch/Source/WebCore/platform/audio/AudioSession.h (293077 => 293078)


--- branches/safari-613-branch/Source/WebCore/platform/audio/AudioSession.h	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/Source/WebCore/platform/audio/AudioSession.h	2022-04-20 05:39:01 UTC (rev 293078)
@@ -46,6 +46,16 @@
     LongFormVideo
 };
 
+enum class AudioSessionCategory : uint8_t {
+    None,
+    AmbientSound,
+    SoloAmbientSound,
+    MediaPlayback,
+    RecordAudio,
+    PlayAndRecord,
+    AudioProcessing,
+};
+
 class AudioSessionRoutingArbitrationClient;
 
 class WEBCORE_EXPORT AudioSession {
@@ -63,15 +73,7 @@
 
     virtual ~AudioSession();
 
-    enum class CategoryType : uint8_t {
-        None,
-        AmbientSound,
-        SoloAmbientSound,
-        MediaPlayback,
-        RecordAudio,
-        PlayAndRecord,
-        AudioProcessing,
-    };
+    using CategoryType = AudioSessionCategory;
     virtual void setCategory(CategoryType, RouteSharingPolicy);
     virtual CategoryType category() const;
 

Modified: branches/safari-613-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (293077 => 293078)


--- branches/safari-613-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2022-04-20 05:39:01 UTC (rev 293078)
@@ -290,9 +290,14 @@
     ALWAYS_LOG(LOGIDENTIFIER, "session moved from index ", pausingSessionIndex, " to ", lastPlayingSessionIndex);
 }
 
-void PlatformMediaSessionManager::sessionStateChanged(PlatformMediaSession&)
+void PlatformMediaSessionManager::sessionStateChanged(PlatformMediaSession& session)
 {
-    scheduleUpdateSessionState();
+    // Call updateSessionState() synchronously if the new state is Playing to ensure
+    // the audio session is active and has the correct category before playback starts.
+    if (session.state() == PlatformMediaSession::Playing)
+        updateSessionState();
+    else
+        scheduleUpdateSessionState();
 }
 
 void PlatformMediaSessionManager::setCurrentSession(PlatformMediaSession& session)

Modified: branches/safari-613-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.h (293077 => 293078)


--- branches/safari-613-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2022-04-20 05:39:01 UTC (rev 293078)
@@ -168,6 +168,7 @@
     WEBCORE_EXPORT void processSystemDidWake();
 
     virtual void resetHaveEverRegisteredAsNowPlayingApplicationForTesting() { };
+    virtual void resetSessionState() { };
 
 protected:
     friend class PlatformMediaSession;

Modified: branches/safari-613-branch/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h (293077 => 293078)


--- branches/safari-613-branch/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.h	2022-04-20 05:39:01 UTC (rev 293078)
@@ -94,6 +94,7 @@
     RemoteCommandListener::RemoteCommandsSet supportedCommands() const final;
 
     void resetHaveEverRegisteredAsNowPlayingApplicationForTesting() final { m_haveEverRegisteredAsNowPlayingApplication = false; };
+    void resetSessionState() final;
 
 private:
 #if !RELEASE_LOG_DISABLED

Modified: branches/safari-613-branch/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm (293077 => 293078)


--- branches/safari-613-branch/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/Source/WebCore/platform/audio/cocoa/MediaSessionManagerCocoa.mm	2022-04-20 05:39:01 UTC (rev 293078)
@@ -196,6 +196,14 @@
     updateSessionState();
 }
 
+void MediaSessionManagerCocoa::resetSessionState()
+{
+    ALWAYS_LOG(LOGIDENTIFIER);
+    m_delayCategoryChangeTimer.stop();
+    m_previousCategory = AudioSession::CategoryType::None;
+    m_previousHadAudibleAudioOrVideoMediaType = false;
+}
+
 void MediaSessionManagerCocoa::beginInterruption(PlatformMediaSession::InterruptionType type)
 {
     if (type == PlatformMediaSession::InterruptionType::SystemInterruption) {

Modified: branches/safari-613-branch/Source/WebCore/testing/Internals.cpp (293077 => 293078)


--- branches/safari-613-branch/Source/WebCore/testing/Internals.cpp	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/Source/WebCore/testing/Internals.cpp	2022-04-20 05:39:01 UTC (rev 293078)
@@ -550,6 +550,7 @@
     page.group().ensureCaptionPreferences().setCaptionsStyleSheetOverride(emptyString());
     PlatformMediaSessionManager::sharedManager().resetHaveEverRegisteredAsNowPlayingApplicationForTesting();
     PlatformMediaSessionManager::sharedManager().resetRestrictions();
+    PlatformMediaSessionManager::sharedManager().resetSessionState();
     PlatformMediaSessionManager::sharedManager().setWillIgnoreSystemInterruptions(true);
 #endif
 #if ENABLE(VIDEO) || ENABLE(WEB_AUDIO)
@@ -5566,29 +5567,26 @@
 #endif
 }
 
-String Internals::audioSessionCategory() const
+auto Internals::audioSessionCategory() const -> AudioSessionCategory
 {
 #if USE(AUDIO_SESSION)
-    switch (AudioSession::sharedSession().category()) {
-    case AudioSession::CategoryType::AmbientSound:
-        return "AmbientSound"_s;
-    case AudioSession::CategoryType::SoloAmbientSound:
-        return "SoloAmbientSound"_s;
-    case AudioSession::CategoryType::MediaPlayback:
-        return "MediaPlayback"_s;
-    case AudioSession::CategoryType::RecordAudio:
-        return "RecordAudio"_s;
-    case AudioSession::CategoryType::PlayAndRecord:
-        return "PlayAndRecord"_s;
-    case AudioSession::CategoryType::AudioProcessing:
-        return "AudioProcessing"_s;
-    case AudioSession::CategoryType::None:
-        return "None"_s;
-    }
+    return AudioSession::sharedSession().category();
+#else
+    return AudioSessionCategory::None;
 #endif
-    return emptyString();
 }
 
+#if ENABLE(VIDEO)
+auto Internals::categoryAtMostRecentPlayback(HTMLMediaElement& element) const -> AudioSessionCategory
+{
+#if USE(AUDIO_SESSION)
+    return element.categoryAtMostRecentPlayback();
+#else
+    return AudioSessionCategory::None;
+#endif
+}
+#endif
+
 double Internals::preferredAudioBufferSize() const
 {
 #if USE(AUDIO_SESSION)

Modified: branches/safari-613-branch/Source/WebCore/testing/Internals.h (293077 => 293078)


--- branches/safari-613-branch/Source/WebCore/testing/Internals.h	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/Source/WebCore/testing/Internals.h	2022-04-20 05:39:01 UTC (rev 293078)
@@ -47,6 +47,10 @@
 #include "MediaUniqueIdentifier.h"
 #endif
 
+#if USE(AUDIO_SESSION)
+#include "AudioSession.h"
+#endif
+
 namespace WebCore {
 
 class AbstractRange;
@@ -877,8 +881,26 @@
     bool shouldAudioTrackPlay(const AudioTrack&);
 #endif
 
+
+#if USE(AUDIO_SESSION)
+    using AudioSessionCategory = WebCore::AudioSessionCategory;
+#else
+    enum class AudioSessionCategory : uint8_t {
+        None,
+        AmbientSound,
+        SoloAmbientSound,
+        MediaPlayback,
+        RecordAudio,
+        PlayAndRecord,
+        AudioProcessing,
+    };
+#endif
+
     bool supportsAudioSession() const;
-    String audioSessionCategory() const;
+    AudioSessionCategory audioSessionCategory() const;
+#if ENABLE(VIDEO)
+    AudioSessionCategory categoryAtMostRecentPlayback(HTMLMediaElement&) const;
+#endif
     double preferredAudioBufferSize() const;
     double currentAudioBufferSize() const;
     bool audioSessionActive() const;

Modified: branches/safari-613-branch/Source/WebCore/testing/Internals.idl (293077 => 293078)


--- branches/safari-613-branch/Source/WebCore/testing/Internals.idl	2022-04-20 05:38:54 UTC (rev 293077)
+++ branches/safari-613-branch/Source/WebCore/testing/Internals.idl	2022-04-20 05:39:01 UTC (rev 293078)
@@ -105,6 +105,16 @@
     "Timeout"
 };
 
+enum AudioSessionCategory {
+    "None",
+    "AmbientSound",
+    "SoloAmbientSound",
+    "MediaPlayback",
+    "RecordAudio",
+    "PlayAndRecord",
+    "AudioProcessing"
+};
+
 enum AutoplayPolicy {
     "Default",
     "Allow",
@@ -950,7 +960,9 @@
     undefined setConsoleMessageListener(StringCallback callback);
 
     readonly attribute boolean supportsAudioSession;
-    DOMString audioSessionCategory();
+    AudioSessionCategory audioSessionCategory();
+    [Conditional=VIDEO] AudioSessionCategory categoryAtMostRecentPlayback(HTMLMediaElement element);
+
     double preferredAudioBufferSize();
     double currentAudioBufferSize();
     boolean audioSessionActive();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to