Title: [268769] trunk
Revision
268769
Author
jer.no...@apple.com
Date
2020-10-20 15:41:46 -0700 (Tue, 20 Oct 2020)

Log Message

[media-session] Basic support for MediaSession.setPositionState() and MediaSession.setActionHandler()
https://bugs.webkit.org/show_bug.cgi?id=217963

Reviewed by Eric Carlson.

Source/WebCore:

Tests: media/media-session/mock-actionHandlers.html
       media/media-session/mock-currentPosition.html

Add basic support for setPositionState() and currentTime calculations of the Media Session
standard, basic support for setActionHandler(), and Internals methods to query the internal
state of both those APIs from layout tests.

* Modules/mediasession/MediaSession.cpp:
(WebCore::MediaSession::setMetadata):
(WebCore::MediaSession::setPlaybackState):
(WebCore::MediaSession::setActionHandler):
(WebCore::MediaSession::handlerForAction const):
(WebCore::MediaSession::setPositionState):
(WebCore::MediaSession::currentPosition const):
* Modules/mediasession/MediaSession.h:
(WebCore::MediaSession::playbackState const):
* Modules/mediasession/MediaSession.idl:
* Modules/mediasession/MediaSessionAction.h:
* Modules/mediasession/MediaSessionActionDetails.idl:
* testing/Internals.cpp:
(WebCore::Internals::currentMediaSessionPosition):
(WebCore::Internals::sendMediaSessionAction):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

* media/media-session/mock-actionHandlers-expected.txt: Added.
* media/media-session/mock-actionHandlers.html: Added.
* media/media-session/mock-currentPosition-expected.txt: Added.
* media/media-session/mock-currentPosition.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (268768 => 268769)


--- trunk/LayoutTests/ChangeLog	2020-10-20 22:33:03 UTC (rev 268768)
+++ trunk/LayoutTests/ChangeLog	2020-10-20 22:41:46 UTC (rev 268769)
@@ -1,3 +1,15 @@
+2020-10-20  Jer Noble  <jer.no...@apple.com>
+
+        [media-session] Basic support for MediaSession.setPositionState() and MediaSession.setActionHandler()
+        https://bugs.webkit.org/show_bug.cgi?id=217963
+
+        Reviewed by Eric Carlson.
+
+        * media/media-session/mock-actionHandlers-expected.txt: Added.
+        * media/media-session/mock-actionHandlers.html: Added.
+        * media/media-session/mock-currentPosition-expected.txt: Added.
+        * media/media-session/mock-currentPosition.html: Added.
+
 2020-10-20  Diego Pino Garcia  <dp...@igalia.com>
 
         [GLIB][GTK] Unreviewed test gardening. Gardened several flaky crash failures.

Added: trunk/LayoutTests/media/media-session/mock-actionHandlers-expected.txt (0 => 268769)


--- trunk/LayoutTests/media/media-session/mock-actionHandlers-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/media-session/mock-actionHandlers-expected.txt	2020-10-20 22:41:46 UTC (rev 268769)
@@ -0,0 +1,39 @@
+Test that synthetic Media Session actions trigger page installed actionHandlers.
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "play"}))
+ACTION: play
+EXPECTED (actionDetails === '{"action":"play"}') OK
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "pause"}))
+ACTION: pause
+EXPECTED (actionDetails === '{"action":"pause"}') OK
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekbackward", seekOffset: -10}))
+ACTION: seekbackward
+EXPECTED (actionDetails === '{"action":"seekbackward","seekOffset":-10}') OK
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekbackward", seekOffset: -10, fastSeek: true}))
+ACTION: seekbackward
+EXPECTED (actionDetails === '{"action":"seekbackward","seekOffset":-10,"fastSeek":true}') OK
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekforward", seekOffset: 10}))
+ACTION: seekforward
+EXPECTED (actionDetails === '{"action":"seekforward","seekOffset":10}') OK
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekforward", seekOffset: 10, fastSeek: true}))
+ACTION: seekforward
+EXPECTED (actionDetails === '{"action":"seekforward","seekOffset":10,"fastSeek":true}') OK
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "previoustrack"}))
+ACTION: previoustrack
+EXPECTED (actionDetails === '{"action":"previoustrack"}') OK
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "nexttrack"}))
+ACTION: nexttrack
+EXPECTED (actionDetails === '{"action":"nexttrack"}') OK
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "skipad"}))
+ACTION: skipad
+EXPECTED (actionDetails === '{"action":"skipad"}') OK
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "stop"}))
+ACTION: stop
+EXPECTED (actionDetails === '{"action":"stop"}') OK
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekto", seekTime: 1}))
+ACTION: seekto
+EXPECTED (actionDetails === '{"action":"seekto","seekTime":1}') OK
+RUN(internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekto", seekTime: 1, fastSeek: true}))
+ACTION: seekto
+EXPECTED (actionDetails === '{"action":"seekto","seekTime":1,"fastSeek":true}') OK
+END OF TEST
+

Added: trunk/LayoutTests/media/media-session/mock-actionHandlers.html (0 => 268769)


--- trunk/LayoutTests/media/media-session/mock-actionHandlers.html	                        (rev 0)
+++ trunk/LayoutTests/media/media-session/mock-actionHandlers.html	2020-10-20 22:41:46 UTC (rev 268769)
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>mock-actionHandlers</title>
+    <script src=""
+    <script>
+    var actionDetails;
+
+    function isEqualActionDetails(setA, setB) {
+        return setA.action ="" setB.action
+            && setA.seekOffset === setB.seekOffset
+            && setA.seekTime === setB.seekTime
+            && setA.fastSeek === setB.fastSeek
+    }
+
+    function testExpectedActionDetails(testFuncString, expected)
+    {
+        let observed = eval(testFuncString);
+        let success = isEqualActionDetails(observed, expected);
+        reportExpected(success, testFuncString, '===', JSON.stringify(expected), JSON.stringify(observed));
+    }
+
+    window.addEventListener('load', async event => {
+        if (!window.internals) {
+            failTest('This test requires Internals');
+            return;
+        }
+
+        let actions = ["play", "pause", "seekbackward", "seekforward", "previoustrack", "nexttrack", "skipad", "stop", "seekto"];
+
+        for (action of actions) {
+            navigator.mediaSession.setActionHandler(action, actionDetails => {
+                consoleWrite(`ACTION: ${actionDetails.action}`);
+                window.actionDetails = actionDetails;
+            });
+        }
+
+        consoleWrite('Test that synthetic Media Session actions trigger page installed actionHandlers.')
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "play"})');
+        testExpectedActionDetails('actionDetails', {action: 'play'});
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "pause"})');
+        testExpectedActionDetails('actionDetails', {action: 'pause'});
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekbackward", seekOffset: -10})');
+        testExpectedActionDetails('actionDetails', {action: 'seekbackward', seekOffset: -10});
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekbackward", seekOffset: -10, fastSeek: true})');
+        testExpectedActionDetails('actionDetails', {action: 'seekbackward', seekOffset: -10, fastSeek: true});
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekforward", seekOffset: 10})');
+        testExpectedActionDetails('actionDetails', {action: 'seekforward', seekOffset: 10});
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekforward", seekOffset: 10, fastSeek: true})');
+        testExpectedActionDetails('actionDetails', {action: 'seekforward', seekOffset: 10, fastSeek: true});
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "previoustrack"})');
+        testExpectedActionDetails('actionDetails', {action: 'previoustrack'});
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "nexttrack"})');
+        testExpectedActionDetails('actionDetails', {action: 'nexttrack'});
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "skipad"})');
+        testExpectedActionDetails('actionDetails', {action: 'skipad'});
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "stop"})');
+        testExpectedActionDetails('actionDetails', {action: 'stop'});
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekto", seekTime: 1})');
+        testExpectedActionDetails('actionDetails', {action: 'seekto', seekTime: 1});
+
+        run('internals.sendMediaSessionAction(navigator.mediaSession, {action: "seekto", seekTime: 1, fastSeek: true})');
+        testExpectedActionDetails('actionDetails', {action: 'seekto', seekTime: 1, fastSeek: true});
+
+        endTest();
+    }, {once: true});
+    </script>
+</head>
+<body>
+
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/media/media-session/mock-currentPosition-expected.txt (0 => 268769)


--- trunk/LayoutTests/media/media-session/mock-currentPosition-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/media/media-session/mock-currentPosition-expected.txt	2020-10-20 22:41:46 UTC (rev 268769)
@@ -0,0 +1,27 @@
+Test that there is no current position before positionState has been set.
+RUN(navigator.mediaSession.setPositionState(null))
+TEST(internals.currentMediaSessionPosition(navigator.mediaSession)) THROWS(DOMException.INVALID_STATE_ERR) OK
+
+Test that current position does not advance when session is "paused".
+RUN(navigator.mediaSession.playbackState = "paused")
+RUN(navigator.mediaSession.setPositionState({ duration: 1, playbackRate: 1, position: 0 }))
+EXPECTED (internals.currentMediaSessionPosition(navigator.mediaSession) == '0') OK
+sleeping for 100ms
+EXPECTED (internals.currentMediaSessionPosition(navigator.mediaSession) == '0') OK
+
+Test that current position does advance when session is "playing".
+RUN(navigator.mediaSession.playbackState = "playing")
+sleeping for 100ms
+EXPECTED (internals.currentMediaSessionPosition(navigator.mediaSession) > '0') OK
+
+Test that currentPosition does not move < 0 when playing backwards.
+RUN(navigator.mediaSession.setPositionState({ duration: 1, playbackRate: -100, position: 1 }))
+sleeping for 100ms
+EXPECTED (internals.currentMediaSessionPosition(navigator.mediaSession) == '0') OK
+
+Test that currentPosition does not advance > duration when playing forwards.
+RUN(navigator.mediaSession.setPositionState({ duration: 1, playbackRate: 100, position: 0 }))
+sleeping for 100ms
+EXPECTED (internals.currentMediaSessionPosition(navigator.mediaSession) == '1') OK
+END OF TEST
+

Added: trunk/LayoutTests/media/media-session/mock-currentPosition.html (0 => 268769)


--- trunk/LayoutTests/media/media-session/mock-currentPosition.html	                        (rev 0)
+++ trunk/LayoutTests/media/media-session/mock-currentPosition.html	2020-10-20 22:41:46 UTC (rev 268769)
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>mock-currentPosition</title>
+    <script src=""
+    <script>
+    window.addEventListener('load', async event => {
+        if (!window.internals) {
+            failTest('This test requires Internals');
+            return;
+        }
+
+        consoleWrite('Test that there is no current position before positionState has been set.')
+        run('navigator.mediaSession.setPositionState(null)');
+        testDOMException('internals.currentMediaSessionPosition(navigator.mediaSession)', "DOMException.INVALID_STATE_ERR");
+
+        consoleWrite('');
+        consoleWrite('Test that current position does not advance when session is "paused".')
+        run('navigator.mediaSession.playbackState = "paused"');
+        run('navigator.mediaSession.setPositionState({ duration: 1, playbackRate: 1, position: 0 })');
+        testExpected('internals.currentMediaSessionPosition(navigator.mediaSession)', 0);
+        consoleWrite('sleeping for 100ms');
+        await sleepFor(100);
+        testExpected('internals.currentMediaSessionPosition(navigator.mediaSession)', 0);
+
+        consoleWrite('');
+        consoleWrite('Test that current position does advance when session is "playing".');
+        run('navigator.mediaSession.playbackState = "playing"');
+        consoleWrite('sleeping for 100ms');
+        await sleepFor(100);
+        testExpected('internals.currentMediaSessionPosition(navigator.mediaSession)', 0, '>');
+
+        consoleWrite('');
+        consoleWrite('Test that currentPosition does not move < 0 when playing backwards.')
+        run('navigator.mediaSession.setPositionState({ duration: 1, playbackRate: -100, position: 1 })');
+        consoleWrite('sleeping for 100ms');
+        await sleepFor(100);
+        testExpected('internals.currentMediaSessionPosition(navigator.mediaSession)', 0);
+
+        consoleWrite('');
+        consoleWrite('Test that currentPosition does not advance > duration when playing forwards.')
+        run('navigator.mediaSession.setPositionState({ duration: 1, playbackRate: 100, position: 0 })');
+        consoleWrite('sleeping for 100ms');
+        await sleepFor(100);
+        testExpected('internals.currentMediaSessionPosition(navigator.mediaSession)', 1);
+        endTest();
+    }, {once: true});
+    </script>
+</head>
+<body>
+
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (268768 => 268769)


--- trunk/Source/WebCore/ChangeLog	2020-10-20 22:33:03 UTC (rev 268768)
+++ trunk/Source/WebCore/ChangeLog	2020-10-20 22:41:46 UTC (rev 268769)
@@ -1,3 +1,35 @@
+2020-10-20  Jer Noble  <jer.no...@apple.com>
+
+        [media-session] Basic support for MediaSession.setPositionState() and MediaSession.setActionHandler()
+        https://bugs.webkit.org/show_bug.cgi?id=217963
+
+        Reviewed by Eric Carlson.
+
+        Tests: media/media-session/mock-actionHandlers.html
+               media/media-session/mock-currentPosition.html
+
+        Add basic support for setPositionState() and currentTime calculations of the Media Session
+        standard, basic support for setActionHandler(), and Internals methods to query the internal
+        state of both those APIs from layout tests.
+
+        * Modules/mediasession/MediaSession.cpp:
+        (WebCore::MediaSession::setMetadata):
+        (WebCore::MediaSession::setPlaybackState):
+        (WebCore::MediaSession::setActionHandler):
+        (WebCore::MediaSession::handlerForAction const):
+        (WebCore::MediaSession::setPositionState):
+        (WebCore::MediaSession::currentPosition const):
+        * Modules/mediasession/MediaSession.h:
+        (WebCore::MediaSession::playbackState const):
+        * Modules/mediasession/MediaSession.idl:
+        * Modules/mediasession/MediaSessionAction.h:
+        * Modules/mediasession/MediaSessionActionDetails.idl:
+        * testing/Internals.cpp:
+        (WebCore::Internals::currentMediaSessionPosition):
+        (WebCore::Internals::sendMediaSessionAction):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2020-10-20  Don Olmstead  <don.olmst...@sony.com>
 
         [WebGPU] Increase portability of GPUBindGroup

Modified: trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp (268768 => 268769)


--- trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp	2020-10-20 22:33:03 UTC (rev 268768)
+++ trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp	2020-10-20 22:41:46 UTC (rev 268769)
@@ -57,31 +57,76 @@
 
 void MediaSession::setPlaybackState(MediaSessionPlaybackState state)
 {
+    if (m_playbackState == state)
+        return;
+
+    auto currentPosition = this->currentPosition();
+    if (m_positionState && currentPosition) {
+        m_positionState->position = *currentPosition;
+        m_timeAtLastPositionUpdate = MonotonicTime::now();
+    }
     m_playbackState = state;
 }
 
-void MediaSession::setActionHandler(MediaSessionAction, RefPtr<MediaSessionActionHandler>&&)
+void MediaSession::setActionHandler(MediaSessionAction action, RefPtr<MediaSessionActionHandler>&& handler)
 {
+    if (handler)
+        m_actionHandlers.set(action, handler);
+    else
+        m_actionHandlers.remove(action);
+    actionHandlersUpdated();
 }
 
+bool MediaSession::hasActionHandler(MediaSessionAction action) const
+{
+    return m_actionHandlers.contains(action);
+}
+
+RefPtr<MediaSessionActionHandler> MediaSession::handlerForAction(MediaSessionAction action) const
+{
+    return m_actionHandlers.get(action);
+}
+
 ExceptionOr<void> MediaSession::setPositionState(Optional<MediaPositionState>&& state)
 {
-    if (!state)
+    if (!state) {
+        m_positionState = WTF::nullopt;
         return { };
-    if (state->duration >= 0
+    }
+
+    if (!(state->duration >= 0
         && state->position >= 0
         && state->position <= state->duration
         && std::isfinite(state->playbackRate)
-        && state->playbackRate != 0)
-        return { };
+        && state->playbackRate))
+        return Exception { TypeError };
 
-    return Exception { TypeError };
+    m_positionState = WTFMove(state);
+    m_lastReportedPosition = m_positionState->position;
+    m_timeAtLastPositionUpdate = MonotonicTime::now();
+    return { };
 }
 
+Optional<double> MediaSession::currentPosition() const
+{
+    if (!m_positionState || !m_lastReportedPosition)
+        return WTF::nullopt;
+
+    auto actualPlaybackRate = m_playbackState == MediaSessionPlaybackState::Playing ? m_positionState->playbackRate : 0;
+
+    auto elapsedTime = (MonotonicTime::now() - m_timeAtLastPositionUpdate) * actualPlaybackRate;
+
+    return std::max(0., std::min(*m_lastReportedPosition + elapsedTime.value(), m_positionState->duration));
+}
+
 void MediaSession::metadataUpdated()
 {
 }
 
+void MediaSession::actionHandlersUpdated()
+{
 }
 
+}
+
 #endif // ENABLE(MEDIA_SESSION)

Modified: trunk/Source/WebCore/Modules/mediasession/MediaSession.h (268768 => 268769)


--- trunk/Source/WebCore/Modules/mediasession/MediaSession.h	2020-10-20 22:33:03 UTC (rev 268768)
+++ trunk/Source/WebCore/Modules/mediasession/MediaSession.h	2020-10-20 22:41:46 UTC (rev 268769)
@@ -31,6 +31,7 @@
 #include "MediaSessionAction.h"
 #include "MediaSessionActionHandler.h"
 #include "MediaSessionPlaybackState.h"
+#include <wtf/MonotonicTime.h>
 #include <wtf/Optional.h>
 #include <wtf/UniqueRef.h>
 #include <wtf/WeakPtr.h>
@@ -53,8 +54,12 @@
 
     void setActionHandler(MediaSessionAction, RefPtr<MediaSessionActionHandler>&&);
     ExceptionOr<void> setPositionState(Optional<MediaPositionState>&&);
+    WEBCORE_EXPORT Optional<double> currentPosition() const;
 
     void metadataUpdated();
+    void actionHandlersUpdated();
+    bool hasActionHandler(MediaSessionAction) const;
+    WEBCORE_EXPORT RefPtr<MediaSessionActionHandler> handlerForAction(MediaSessionAction) const;
 
 private:
     explicit MediaSession(Navigator&);
@@ -62,6 +67,10 @@
     WeakPtr<Navigator> m_navigator;
     RefPtr<MediaMetadata> m_metadata;
     MediaSessionPlaybackState m_playbackState { MediaSessionPlaybackState::None };
+    Optional<MediaPositionState> m_positionState;
+    Optional<double> m_lastReportedPosition;
+    MonotonicTime m_timeAtLastPositionUpdate;
+    HashMap<MediaSessionAction, RefPtr<MediaSessionActionHandler>, WTF::IntHash<MediaSessionAction>, WTF::StrongEnumHashTraits<MediaSessionAction>> m_actionHandlers;
 };
 
 }

Modified: trunk/Source/WebCore/Modules/mediasession/MediaSession.idl (268768 => 268769)


--- trunk/Source/WebCore/Modules/mediasession/MediaSession.idl	2020-10-20 22:33:03 UTC (rev 268768)
+++ trunk/Source/WebCore/Modules/mediasession/MediaSession.idl	2020-10-20 22:41:46 UTC (rev 268769)
@@ -27,6 +27,7 @@
     Conditional=MEDIA_SESSION,
     Exposed=Window,
     ImplementationLacksVTable,
+    ExportMacro=WEBCORE_EXPORT,
 ] interface MediaSession {
     attribute MediaMetadata? metadata;
 

Modified: trunk/Source/WebCore/Modules/mediasession/MediaSessionAction.h (268768 => 268769)


--- trunk/Source/WebCore/Modules/mediasession/MediaSessionAction.h	2020-10-20 22:33:03 UTC (rev 268768)
+++ trunk/Source/WebCore/Modules/mediasession/MediaSessionAction.h	2020-10-20 22:41:46 UTC (rev 268769)
@@ -43,4 +43,23 @@
 
 } // namespace WebCore
 
+namespace WTF {
+
+template<> struct EnumTraits<WebCore::MediaSessionAction> {
+    using values = EnumValues<
+        WebCore::MediaSessionAction,
+        WebCore::MediaSessionAction::Play,
+        WebCore::MediaSessionAction::Pause,
+        WebCore::MediaSessionAction::Seekbackward,
+        WebCore::MediaSessionAction::Seekforward,
+        WebCore::MediaSessionAction::Previoustrack,
+        WebCore::MediaSessionAction::Nexttrack,
+        WebCore::MediaSessionAction::Skipad,
+        WebCore::MediaSessionAction::Stop,
+        WebCore::MediaSessionAction::Seekto
+    >;
+};
+
+}
+
 #endif // ENABLE(MEDIA_SESSION)

Modified: trunk/Source/WebCore/Modules/mediasession/MediaSessionActionDetails.idl (268768 => 268769)


--- trunk/Source/WebCore/Modules/mediasession/MediaSessionActionDetails.idl	2020-10-20 22:33:03 UTC (rev 268768)
+++ trunk/Source/WebCore/Modules/mediasession/MediaSessionActionDetails.idl	2020-10-20 22:41:46 UTC (rev 268769)
@@ -26,6 +26,7 @@
 [
     Conditional=MEDIA_SESSION,
     JSGenerateToJSObject,
+    ExportMacro=WEBCORE_EXPORT,
 ] dictionary MediaSessionActionDetails {
     required MediaSessionAction action;
     double? seekOffset;

Modified: trunk/Source/WebCore/testing/Internals.cpp (268768 => 268769)


--- trunk/Source/WebCore/testing/Internals.cpp	2020-10-20 22:33:03 UTC (rev 268768)
+++ trunk/Source/WebCore/testing/Internals.cpp	2020-10-20 22:41:46 UTC (rev 268769)
@@ -128,6 +128,8 @@
 #include "MediaProducer.h"
 #include "MediaRecorderProvider.h"
 #include "MediaResourceLoader.h"
+#include "MediaSession.h"
+#include "MediaSessionActionDetails.h"
 #include "MediaStreamTrack.h"
 #include "MediaUsageInfo.h"
 #include "MemoryCache.h"
@@ -5963,4 +5965,23 @@
 
 #endif
 
+#if ENABLE(MEDIA_SESSION)
+ExceptionOr<double> Internals::currentMediaSessionPosition(const MediaSession& session)
+{
+    if (auto currentPosition = session.currentPosition())
+        return *currentPosition;
+    return Exception { InvalidStateError };
+}
+
+ExceptionOr<void> Internals::sendMediaSessionAction(MediaSession& session, const MediaSessionActionDetails& actionDetails)
+{
+    if (auto handler = session.handlerForAction(actionDetails.action)) {
+        handler->handleEvent(actionDetails);
+        return { };
+    }
+    return Exception { InvalidStateError };
+}
+#endif
+
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/Internals.h (268768 => 268769)


--- trunk/Source/WebCore/testing/Internals.h	2020-10-20 22:33:03 UTC (rev 268768)
+++ trunk/Source/WebCore/testing/Internals.h	2020-10-20 22:41:46 UTC (rev 268769)
@@ -80,7 +80,6 @@
 class InternalsSetLike;
 class Location;
 class MallocStatistics;
-class MediaSession;
 class MediaStream;
 class MediaStreamTrack;
 class MemoryInfo;
@@ -127,6 +126,11 @@
 class WebXRTest;
 #endif
 
+#if ENABLE(MEDIA_SESSION)
+class MediaSession;
+struct MediaSessionActionDetails;
+#endif
+
 template<typename IDLType> class DOMPromiseDeferred;
 
 struct MockWebAuthenticationConfiguration;
@@ -1048,6 +1052,11 @@
     ExceptionOr<AttachmentThumbnailInfo> attachmentThumbnailInfo(const HTMLAttachmentElement&);
 #endif
 
+#if ENABLE(MEDIA_SESSION)
+    ExceptionOr<double> currentMediaSessionPosition(const MediaSession&);
+    ExceptionOr<void> sendMediaSessionAction(MediaSession&, const MediaSessionActionDetails&);
+#endif
+
 private:
     explicit Internals(Document&);
     Document* contextDocument() const;

Modified: trunk/Source/WebCore/testing/Internals.idl (268768 => 268769)


--- trunk/Source/WebCore/testing/Internals.idl	2020-10-20 22:33:03 UTC (rev 268768)
+++ trunk/Source/WebCore/testing/Internals.idl	2020-10-20 22:41:46 UTC (rev 268769)
@@ -952,4 +952,7 @@
     undefined setContentSizeCategory(ContentSizeCategory category);
 
     [Conditional=ATTACHMENT_ELEMENT, MayThrowException] AttachmentThumbnailInfo attachmentThumbnailInfo(HTMLAttachmentElement element);
+
+    [Conditional=MEDIA_SESSION, MayThrowException] double currentMediaSessionPosition(MediaSession session);
+    [Conditional=MEDIA_SESSION, MayThrowException] undefined sendMediaSessionAction(MediaSession session, MediaSessionActionDetails actionDetails);
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to