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

Changeset 278336 in webkit


Ignore:
Timestamp:
Jun 1, 2021, 6:20:38 PM (5 years ago)
Author:
Jean-Yves Avenard
Message:

LayoutTests/imported/w3c:
MediaSession.coordinator should not be optional, relying on coordinator state change instead
https://bugs.webkit.org/show_bug.cgi?id=226328
rdar://77461335

Reviewed by Eric Carlson.

  • web-platform-tests/mediasession/idlharness.window-expected.txt:

Source/WebCore:
MediaSession.coordinator should not be optional, relying on coordinator state change instead
https://bugs.webkit.org/show_bug.cgi?id=226328
rdar://77461335

Reviewed by Eric Carlson.

The coordinator was a read-only optional attribute of the MediaSession element.
Testing if the attribute was to be used to determine if a MediaSessionCoordinator
was now available and for the MediaSession to join it. This made the use of an external
polyfill difficult and enforcing the validity of an user created custom
MediaSessionCoordinator due to IDL semantics limitations hard.
We instead always create a MediaSessionCoordinator which in its default state is Closed.
Once this state is changed to Waiting and an event is fire the MediaSession can now
join it.

  • Modules/mediasession/MediaSession.cpp:

(WebCore::MediaSession::MediaSession): MediaSession no longer needs to fire event.
Remove no longer necessary inheritance and async event queue.
(WebCore::MediaSession::create): Drive-by fix, don't call suspendIfNeeded() in the constructor.
(WebCore::MediaSession::createCoordinator): Make method private.

  • Modules/mediasession/MediaSession.h:

(WebCore::MediaSession::coordinator const): MediaSessionCoordinator always exists. Return reference instead.

  • Modules/mediasession/MediaSession.idl: Amend definition, remove EventHandler
  • Modules/mediasession/MediaSessionCoordinator.cpp:

(WebCore::MediaSessionCoordinator::create):
(WebCore::MediaSessionCoordinator::MediaSessionCoordinator):
(WebCore::MediaSessionCoordinator::setMediaSessionCoordinatorPrivate):
(WebCore::MediaSessionCoordinator::virtualHasPendingActivity const):
(WebCore::MediaSessionCoordinator::join):
(WebCore::MediaSessionCoordinator::close):
(WebCore::MediaSessionCoordinator::coordinatorStateChanged):

  • Modules/mediasession/MediaSessionCoordinator.h:
  • Modules/mediasession/MediaSessionCoordinator.idl: Added new EventHandler attribute.
  • Modules/mediasession/MediaSessionCoordinatorMixin.idl: Update for new API definition.
  • dom/EventNames.h:
  • dom/EventTargetFactory.in:
  • page/Page.cpp:

(WebCore::Page::setMediaSessionCoordinator):
(WebCore::Page::invalidateMediaSessionCoordinator):

  • testing/Internals.cpp:

(WebCore::Internals::registerMockMediaSessionCoordinator):

Tools:
MediaSession.coordinator should not be optional, relying on coordinator readyState change instead
https://bugs.webkit.org/show_bug.cgi?id=226328
rdar://77461335

Reviewed by Eric Carlson.

  • TestWebKitAPI/Tests/WebKit/MediaSessionCoordinatorTest.mm:

(TestWebKitAPI::MediaSessionCoordinatorTest::createCoordinator): Change test to match new API,
using coordinatorstatechange event instead.

  • TestWebKitAPI/Tests/WebKitCocoa/media-remote.html:

LayoutTests:
MediaSession.coordinator should not be optional, relying on coordinator readyState change instead
https://bugs.webkit.org/show_bug.cgi?id=226328
rdar://77461335

Reviewed by Eric Carlson.

  • media/media-session/mock-coordinator-expected.txt:
  • media/media-session/mock-coordinator.html: Change test to match new API.
Location:
trunk
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r278329 r278336  
     12021-06-01  Jean-Yves Avenard  <jya@apple.com>
     2
     3        MediaSession.coordinator should not be optional, relying on coordinator readyState change instead
     4        https://bugs.webkit.org/show_bug.cgi?id=226328
     5        rdar://77461335
     6
     7        Reviewed by Eric Carlson.
     8
     9        * media/media-session/mock-coordinator-expected.txt:
     10        * media/media-session/mock-coordinator.html: Change test to match new API.
     11
    1122021-06-01  Chris Dumez  <cdumez@apple.com>
    213
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r278299 r278336  
     12021-06-01  Jean-Yves Avenard  <jya@apple.com>
     2
     3        MediaSession.coordinator should not be optional, relying on coordinator state change instead
     4        https://bugs.webkit.org/show_bug.cgi?id=226328
     5        rdar://77461335
     6
     7        Reviewed by Eric Carlson.
     8
     9        * web-platform-tests/mediasession/idlharness.window-expected.txt:
     10
    1112021-06-01  Cathie Chen  <cathiechen@igalia.com>
    212
  • trunk/LayoutTests/imported/w3c/web-platform-tests/mediasession/idlharness.window-expected.txt

    r274983 r278336  
    1313PASS Navigator includes NavigatorPlugins: member names are unique
    1414PASS Navigator includes NavigatorConcurrentHardware: member names are unique
    15 FAIL MediaSession interface: existence and properties of interface object assert_equals: prototype of self's property "MediaSession" is not Function.prototype expected function "function () {
    16     [native code]
    17 }" but got function "function EventTarget() {
    18     [native code]
    19 }"
     15PASS MediaSession interface: existence and properties of interface object
    2016PASS MediaSession interface object length
    2117PASS MediaSession interface object name
    22 FAIL MediaSession interface: existence and properties of interface prototype object assert_equals: prototype of MediaSession.prototype is not Object.prototype expected object "[object Object]" but got object "[object EventTarget]"
     18PASS MediaSession interface: existence and properties of interface prototype object
    2319PASS MediaSession interface: existence and properties of interface prototype object's "constructor" property
    2420PASS MediaSession interface: existence and properties of interface prototype object's @@unscopables property
  • trunk/LayoutTests/media/media-session/mock-coordinator-expected.txt

    r278143 r278336  
    11
    2 ** There should be no mediaSession.coordinator initially.
    3 EXPECTED (navigator.mediaSession.coordinator == 'undefined') OK
    4 
    5 ** Test that mediaSession.coordinatorchange event is fired when it changes.
     2** There mediaSession.coordinator.state should be closed initially.
     3EXPECTED (navigator.mediaSession.coordinator.state == 'closed') OK
     4
     5** Test that mediaSession.coordinator.coordinatorstatechange event is fired when it changes.
    66RUN(internals.registerMockMediaSessionCoordinator(changeHandler))
    7 EVENT(coordinatorchange)
    8 EXPECTED (navigator.mediaSession.coordinator != 'undefined') OK
    9 
    10 ** navigator.mediaSession.coordinator.state should be "waiting" intitially
     7EVENT(coordinatorstatechange STATE(waiting)
     8
     9** navigator.mediaSession.coordinator.state should be "waiting" initially
    1110EXPECTED (navigator.mediaSession.coordinator.state == 'waiting') OK
    1211
     
    7978RUN(internals.setMockMediaSessionCoordinatorCommandsShouldFail(false))
    8079RUN(promise = navigator.mediaSession.coordinator.join())
     80EVENT(coordinatorstatechange STATE(joined)
    8181Promise resolved OK
    8282EXPECTED (navigator.mediaSession.coordinator.state == 'joined') OK
    83 EXPECTED (latestChange == 'coordinatorStateChanged') OK
    8483
    8584** Test that when coordinator methods succeed, promises resolve and mediaSession action handlers are called.
     
    150149** Leave the session
    151150RUN(navigator.mediaSession.coordinator.leave())
     151EXPECTED (latestChange == 'playbackStateChanged') OK
     152EXPECTED (latestChange == 'playbackStateChanged') OK
     153EXPECTED (latestChange == 'playbackStateChanged') OK
     154EVENT(coordinatorstatechange STATE(closed)
    152155EXPECTED (navigator.mediaSession.coordinator.state == 'closed') OK
    153 EXPECTED (latestChange == 'coordinatorStateChanged') OK
    154156
    155157** Test that when coordinator methods fail and promises reject after mediaSession.leave() has been called.
  • trunk/LayoutTests/media/media-session/mock-coordinator.html

    r278143 r278336  
    3434        let changePromise = () => {
    3535            return new Promise(resolve => {
    36                 navigator.mediaSession.addEventListener('coordinatorchange', (event) => {
    37                     consoleWrite(`EVENT(${event.type})`);
     36                navigator.mediaSession.coordinator.addEventListener('coordinatorstatechange', (event) => {
     37                    consoleWrite(`EVENT(${event.type} STATE(${navigator.mediaSession.coordinator.state})`);
    3838                    resolve();
    39                 });
     39                }, { once: true });
    4040            });
    4141        }
     
    4444
    4545        consoleWrite('');
    46         consoleWrite('** There should be no mediaSession.coordinator initially.')
    47 
    48         testExpected('navigator.mediaSession.coordinator', undefined);
    49 
    50         consoleWrite('');
    51         consoleWrite('** Test that mediaSession.coordinatorchange event is fired when it changes.')
     46        consoleWrite('** There mediaSession.coordinator.state should be closed initially.');
     47
     48        testExpected('navigator.mediaSession.coordinator.state', "closed");
     49
     50        consoleWrite('');
     51        consoleWrite('** Test that mediaSession.coordinator.coordinatorstatechange event is fired when it changes.');
    5252
    5353        run('internals.registerMockMediaSessionCoordinator(changeHandler)');
    5454
    5555        await changePromise();
    56        
    57         testExpected('navigator.mediaSession.coordinator', undefined, '!=');
    5856
    5957        ['play', 'pause', 'seekto'].forEach(action => {
     
    121119        // Before joining
    122120        consoleWrite('');
    123         consoleWrite('** navigator.mediaSession.coordinator.state should be "waiting" intitially')
     121        consoleWrite('** navigator.mediaSession.coordinator.state should be "waiting" initially')
    124122        testExpected('navigator.mediaSession.coordinator.state', 'waiting');
    125123
     
    160158        run('internals.setMockMediaSessionCoordinatorCommandsShouldFail(false)');
    161159        run('promise = navigator.mediaSession.coordinator.join()');
     160        await changePromise();
    162161        await shouldResolve(promise).then(() => { }).catch(() => { });
    163162        testExpected('navigator.mediaSession.coordinator.state', 'joined');
    164         testExpected('latestChange', 'coordinatorStateChanged');
    165163
    166164        consoleWrite('');
     
    190188        consoleWrite('** Leave the session')
    191189        run('navigator.mediaSession.coordinator.leave()');
     190        await changePromise();
    192191        testExpected('navigator.mediaSession.coordinator.state', 'closed');
    193         await testExpectedEventually('latestChange', 'coordinatorStateChanged', '==', 100);
     192
    194193        latestChange = '';
    195194
  • trunk/Source/WebCore/ChangeLog

    r278333 r278336  
     12021-06-01  Jean-Yves Avenard  <jya@apple.com>
     2
     3        MediaSession.coordinator should not be optional, relying on coordinator state change instead
     4        https://bugs.webkit.org/show_bug.cgi?id=226328
     5        rdar://77461335
     6
     7        Reviewed by Eric Carlson.
     8
     9        The coordinator was a read-only optional attribute of the MediaSession element.
     10        Testing if the attribute was to be used to determine if a MediaSessionCoordinator
     11        was now available and for the MediaSession to join it. This made the use of an external
     12        polyfill difficult and enforcing the validity of an user created custom
     13        MediaSessionCoordinator due to IDL semantics limitations hard.
     14        We instead always create a MediaSessionCoordinator which in its default state is Closed.
     15        Once this state is changed to Waiting and an event is fire the MediaSession can now
     16        join it.
     17
     18        * Modules/mediasession/MediaSession.cpp:
     19        (WebCore::MediaSession::MediaSession): MediaSession no longer needs to fire event.
     20        Remove no longer necessary inheritance and async event queue.
     21        (WebCore::MediaSession::create): Drive-by fix, don't call suspendIfNeeded() in the constructor.
     22        (WebCore::MediaSession::createCoordinator): Make method private.
     23        * Modules/mediasession/MediaSession.h:
     24        (WebCore::MediaSession::coordinator const): MediaSessionCoordinator always exists. Return reference instead.
     25        * Modules/mediasession/MediaSession.idl: Amend definition, remove EventHandler
     26        * Modules/mediasession/MediaSessionCoordinator.cpp:
     27        (WebCore::MediaSessionCoordinator::create):
     28        (WebCore::MediaSessionCoordinator::MediaSessionCoordinator):
     29        (WebCore::MediaSessionCoordinator::setMediaSessionCoordinatorPrivate):
     30        (WebCore::MediaSessionCoordinator::virtualHasPendingActivity const):
     31        (WebCore::MediaSessionCoordinator::join):
     32        (WebCore::MediaSessionCoordinator::close):
     33        (WebCore::MediaSessionCoordinator::coordinatorStateChanged):
     34        * Modules/mediasession/MediaSessionCoordinator.h:
     35        * Modules/mediasession/MediaSessionCoordinator.idl: Added new EventHandler attribute.
     36        * Modules/mediasession/MediaSessionCoordinatorMixin.idl: Update for new API definition.
     37        * dom/EventNames.h:
     38        * dom/EventTargetFactory.in:
     39        * page/Page.cpp:
     40        (WebCore::Page::setMediaSessionCoordinator):
     41        (WebCore::Page::invalidateMediaSessionCoordinator):
     42        * testing/Internals.cpp:
     43        (WebCore::Internals::registerMockMediaSessionCoordinator):
     44
    1452021-06-01  Chris Dumez  <cdumez@apple.com>
    246
  • trunk/Source/WebCore/Modules/mediasession/MediaSession.cpp

    r278253 r278336  
    129129Ref<MediaSession> MediaSession::create(Navigator& navigator)
    130130{
    131     return adoptRef(*new MediaSession(navigator));
     131    auto session = adoptRef(*new MediaSession(navigator));
     132    session->suspendIfNeeded();
     133    return session;
    132134}
    133135
     
    135137    : ActiveDOMObject(navigator.scriptExecutionContext())
    136138    , m_navigator(makeWeakPtr(navigator))
    137     , m_asyncEventQueue(MainThreadGenericEventQueue::create(*this))
    138139{
    139140    m_logger = makeRefPtr(Document::sharedLogger());
     
    142143#if ENABLE(MEDIA_SESSION_COORDINATOR)
    143144    auto* frame = navigator.frame();
    144     if (auto* page = frame ? frame->page() : nullptr) {
    145         if (auto coordinatorPrivate = page->mediaSessionCoordinator())
    146             createCoordinator(*coordinatorPrivate);
    147     }
    148 #endif
    149 
    150     suspendIfNeeded();
     145    if (auto* page = frame ? frame->page() : nullptr)
     146        createCoordinator(page->mediaSessionCoordinator());
     147#endif
    151148
    152149    ALWAYS_LOG(LOGIDENTIFIER);
     
    154151
    155152MediaSession::~MediaSession() = default;
    156 
    157 bool MediaSession::virtualHasPendingActivity() const
    158 {
    159     return m_asyncEventQueue->hasPendingActivity();
    160 }
    161153
    162154void MediaSession::suspend(ReasonForSuspension reason)
     
    201193}
    202194
    203 void MediaSession::createCoordinator(Ref<MediaSessionCoordinatorPrivate>&& coordinatorPrivate)
     195void MediaSession::createCoordinator(MediaSessionCoordinatorPrivate* coordinatorPrivate)
    204196{
    205197    ALWAYS_LOG(LOGIDENTIFIER);
     
    208200        m_coordinator->setMediaSession(nullptr);
    209201
    210     m_coordinator = MediaSessionCoordinator::create(WTFMove(coordinatorPrivate));
    211 
    212     if (m_coordinator)
    213         m_coordinator->setMediaSession(this);
    214 
    215     m_asyncEventQueue->enqueueEvent(Event::create(eventNames().coordinatorchangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
     202    m_coordinator = MediaSessionCoordinator::create(scriptExecutionContext(), coordinatorPrivate);
     203    m_coordinator->setMediaSession(this);
    216204}
    217205#endif
  • trunk/Source/WebCore/Modules/mediasession/MediaSession.h

    r278253 r278336  
    2929
    3030#include "ActiveDOMObject.h"
    31 #include "EventTarget.h"
    32 #include "GenericEventQueue.h"
     31#include "ExceptionOr.h"
    3332#include "MediaPositionState.h"
    3433#include "MediaSessionAction.h"
     
    5352template<typename> class DOMPromiseDeferred;
    5453
    55 class MediaSession : public RefCounted<MediaSession>, public ActiveDOMObject, public EventTargetWithInlineData {
     54class MediaSession : public RefCounted<MediaSession>, public ActiveDOMObject, public CanMakeWeakPtr<MediaSession> {
    5655    WTF_MAKE_FAST_ALLOCATED;
    5756public:
     
    8180    void setReadyState(MediaSessionReadyState);
    8281
    83     MediaSessionCoordinator* coordinator() const { return m_coordinator.get(); }
    84     WEBCORE_EXPORT void createCoordinator(Ref<MediaSessionCoordinatorPrivate>&&);
     82    MediaSessionCoordinator& coordinator() const { return *m_coordinator; }
    8583#endif
    8684
     
    9896
    9997    const Logger& logger() const { return *m_logger.get(); }
    100 
    101     // EventTarget
    102     using RefCounted::ref;
    103     using RefCounted::deref;
    10498
    10599    class Observer : public CanMakeWeakPtr<Observer> {
     
    131125    void notifyReadyStateObservers();
    132126
    133     // EventTarget
    134     void refEventTarget() final { ref(); }
    135     void derefEventTarget() final { deref(); }
    136     EventTargetInterface eventTargetInterface() const final { return MediaSessionEventTargetInterfaceType; }
    137     ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
     127    void createCoordinator(MediaSessionCoordinatorPrivate*);
    138128
    139129    // ActiveDOMObject
    140130    const char* activeDOMObjectName() const final { return "MediaSession"; }
    141     bool virtualHasPendingActivity() const final;
    142131    void suspend(ReasonForSuspension) final;
    143132    void stop() final;
     
    156145
    157146    WeakHashSet<Observer> m_observers;
    158     UniqueRef<MainThreadGenericEventQueue> m_asyncEventQueue;
    159147
    160148#if ENABLE(MEDIA_SESSION_COORDINATOR)
  • trunk/Source/WebCore/Modules/mediasession/MediaSession.idl

    r278222 r278336  
    2929    Exposed=Window,
    3030    ExportMacro=WEBCORE_EXPORT,
    31     JSGenerateToJSObject,
    32 ] interface MediaSession : EventTarget
     31] interface MediaSession
    3332{
    3433    attribute MediaMetadata? metadata;
  • trunk/Source/WebCore/Modules/mediasession/MediaSessionCoordinator.cpp

    r278253 r278336  
    2929#if ENABLE(MEDIA_SESSION_COORDINATOR)
    3030
     31#include "EventNames.h"
    3132#include "JSDOMException.h"
    3233#include "JSDOMPromiseDeferred.h"
     
    4849}
    4950
    50 Ref<MediaSessionCoordinator> MediaSessionCoordinator::create(Ref<MediaSessionCoordinatorPrivate>&& privateCoordinator)
    51 {
    52     return adoptRef(*new MediaSessionCoordinator(WTFMove(privateCoordinator)));
    53 }
    54 
    55 MediaSessionCoordinator::MediaSessionCoordinator(Ref<MediaSessionCoordinatorPrivate>&& privateCoordinator)
    56     : m_privateCoordinator(WTFMove(privateCoordinator))
     51Ref<MediaSessionCoordinator> MediaSessionCoordinator::create(ScriptExecutionContext* context, RefPtr<MediaSessionCoordinatorPrivate>&& privateCoordinator)
     52{
     53    auto coordinator = adoptRef(*new MediaSessionCoordinator(context, WTFMove(privateCoordinator)));
     54    coordinator->suspendIfNeeded();
     55    return coordinator;
     56}
     57
     58MediaSessionCoordinator::MediaSessionCoordinator(ScriptExecutionContext* context, RefPtr<MediaSessionCoordinatorPrivate>&& privateCoordinator)
     59    : ActiveDOMObject(context)
    5760    , m_logger(makeRef(Document::sharedLogger()))
    5861    , m_logIdentifier(nextCoordinatorLogIdentifier())
     62    , m_asyncEventQueue(MainThreadGenericEventQueue::create(*this))
    5963{
    6064    ALWAYS_LOG(LOGIDENTIFIER);
    6165
     66    if (privateCoordinator)
     67        setMediaSessionCoordinatorPrivate(*privateCoordinator);
     68}
     69
     70void MediaSessionCoordinator::setMediaSessionCoordinatorPrivate(Ref<MediaSessionCoordinatorPrivate>&& privateCoordinator)
     71{
     72    ALWAYS_LOG(LOGIDENTIFIER);
     73    if (m_privateCoordinator)
     74        m_privateCoordinator->leave();
     75    m_privateCoordinator = WTFMove(privateCoordinator);
    6276    m_privateCoordinator->setLogger(m_logger.copyRef(), m_logIdentifier);
    6377    m_privateCoordinator->setClient(makeWeakPtr(this));
     78    coordinatorStateChanged(MediaSessionCoordinatorState::Waiting);
    6479}
    6580
    6681MediaSessionCoordinator::~MediaSessionCoordinator() = default;
     82
     83void MediaSessionCoordinator::eventListenersDidChange()
     84{
     85    m_hasCoordinatorsStateChangeEventListener = hasEventListeners(eventNames().coordinatorstatechangeEvent);
     86}
     87
     88bool MediaSessionCoordinator::virtualHasPendingActivity() const
     89{
     90    // Need to keep the JS wrapper alive as long as it may still fire events in the future.
     91    return shouldFireEvents();
     92}
    6793
    6894void MediaSessionCoordinator::join(DOMPromiseDeferred<void>&& promise)
     
    76102        return;
    77103    }
     104    ASSERT(m_privateCoordinator, "We must be in Waiting state if no private coordinator is set");
    78105
    79106    m_privateCoordinator->join([protectedThis = makeRefPtr(*this), identifier, promise = WTFMove(promise)] (std::optional<Exception>&& exception) mutable {
     
    89116        }
    90117
    91         protectedThis->m_state = MediaSessionCoordinatorState::Joined;
     118        protectedThis->coordinatorStateChanged(MediaSessionCoordinatorState::Joined);
     119
    92120        promise.resolve();
    93121    });
     
    108136{
    109137    ALWAYS_LOG(LOGIDENTIFIER);
    110     m_state = MediaSessionCoordinatorState::Closed;
     138    coordinatorStateChanged(MediaSessionCoordinatorState::Closed);
    111139    if (!m_privateCoordinator)
    112140        return;
     
    382410}
    383411
     412bool MediaSessionCoordinator::shouldFireEvents() const
     413{
     414    return m_hasCoordinatorsStateChangeEventListener && m_session;
     415}
     416
     417
    384418void MediaSessionCoordinator::coordinatorStateChanged(MediaSessionCoordinatorState state)
    385419{
     
    388422    m_state = state;
    389423    ALWAYS_LOG(LOGIDENTIFIER, m_state);
     424    if (shouldFireEvents())
     425        m_asyncEventQueue->enqueueEvent(Event::create(eventNames().coordinatorstatechangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
    390426}
    391427
  • trunk/Source/WebCore/Modules/mediasession/MediaSessionCoordinator.h

    r278253 r278336  
    2828#if ENABLE(MEDIA_SESSION_COORDINATOR)
    2929
     30#include "ActiveDOMObject.h"
     31#include "EventTarget.h"
     32#include "GenericEventQueue.h"
    3033#include "MediaSession.h"
    3134#include "MediaSessionCoordinatorPrivate.h"
     
    4245    : public RefCounted<MediaSessionCoordinator>
    4346    , public MediaSessionCoordinatorClient
    44     , public MediaSession::Observer {
     47    , public MediaSession::Observer
     48    , public ActiveDOMObject
     49    , public EventTargetWithInlineData  {
     50    WTF_MAKE_FAST_ALLOCATED;
    4551public:
    46     WEBCORE_EXPORT static Ref<MediaSessionCoordinator> create(Ref<MediaSessionCoordinatorPrivate>&&);
     52    WEBCORE_EXPORT static Ref<MediaSessionCoordinator> create(ScriptExecutionContext*, RefPtr<MediaSessionCoordinatorPrivate>&&);
    4753    WEBCORE_EXPORT ~MediaSessionCoordinator();
     54    WEBCORE_EXPORT void setMediaSessionCoordinatorPrivate(Ref<MediaSessionCoordinatorPrivate>&&);
    4855
    4956    void join(DOMPromiseDeferred<void>&&);
     
    6370    using MediaSessionCoordinatorClient::weakPtrFactory;
    6471    using WeakValueType = MediaSessionCoordinatorClient::WeakValueType;
     72    using RefCounted::ref;
     73    using RefCounted::deref;
    6574
    6675private:
    67     explicit MediaSessionCoordinator(Ref<MediaSessionCoordinatorPrivate>&&);
     76    MediaSessionCoordinator(ScriptExecutionContext*, RefPtr<MediaSessionCoordinatorPrivate>&&);
     77
     78    // EventTarget
     79    void refEventTarget() final { ref(); }
     80    void derefEventTarget() final { deref(); }
     81    EventTargetInterface eventTargetInterface() const final { return MediaSessionCoordinatorEventTargetInterfaceType; }
     82    ScriptExecutionContext* scriptExecutionContext() const final { return ContextDestructionObserver::scriptExecutionContext(); }
     83    void eventListenersDidChange() final;
     84
     85    // ActiveDOMObject
     86    const char* activeDOMObjectName() const final { return "MediaSessionCoordinator"; }
     87    bool virtualHasPendingActivity() const final;
    6888
    6989    // MediaSession::Observer
     
    86106    static WTFLogChannel& logChannel();
    87107    static const char* logClassName() { return "MediaSessionCoordinator"; }
     108    bool shouldFireEvents() const;
    88109
    89110    WeakPtr<MediaSession> m_session;
    90     MediaSessionCoordinatorState m_state { MediaSessionCoordinatorState::Waiting };
    91111    RefPtr<MediaSessionCoordinatorPrivate> m_privateCoordinator;
    92     Ref<const Logger> m_logger;
     112    const Ref<const Logger> m_logger;
    93113    const void* m_logIdentifier;
     114    UniqueRef<MainThreadGenericEventQueue> m_asyncEventQueue;
     115    MediaSessionCoordinatorState m_state { MediaSessionCoordinatorState::Closed };
     116    bool m_hasCoordinatorsStateChangeEventListener { false };
    94117};
    95118
  • trunk/Source/WebCore/Modules/mediasession/MediaSessionCoordinator.idl

    r275314 r278336  
    2525
    2626[
     27    ActiveDOMObject,
    2728    Conditional=MEDIA_SESSION_COORDINATOR,
    2829    EnabledBySetting=MediaSessionCoordinator,
    2930    Exposed=Window,
    3031    ExportMacro=WEBCORE_EXPORT,
    31 ] interface MediaSessionCoordinator {
     32    JSGenerateToJSObject,
     33] interface MediaSessionCoordinator : EventTarget {
    3234
    3335    Promise<undefined> join();
     
    3537
    3638    readonly attribute MediaSessionCoordinatorState state;
     39    attribute EventHandler oncoordinatorstatechange;
     40   
    3741    readonly attribute DOMString? identifier;
    3842
  • trunk/Source/WebCore/Modules/mediasession/MediaSessionCoordinatorMixin.idl

    r275314 r278336  
    2828    EnabledBySetting=MediaSessionCoordinator,
    2929] interface mixin MediaSessionCoordinatorMixin {
    30     readonly attribute MediaSessionCoordinator? coordinator;
    31     attribute EventHandler oncoordinatorchange;
     30    readonly attribute MediaSessionCoordinator coordinator;
    3231    attribute MediaSessionReadyState readyState;
    3332};
  • trunk/Source/WebCore/dom/EventNames.h

    r275431 r278336  
    102102    macro(contextmenu) \
    103103    macro(controllerchange) \
    104     macro(coordinatorchange) \
     104    macro(coordinatorstatechange) \
    105105    macro(copy) \
    106106    macro(cuechange) \
  • trunk/Source/WebCore/dom/EventTargetFactory.in

    r275151 r278336  
    2424MediaQueryList
    2525MediaRecorder conditional=MEDIA_STREAM
    26 MediaSession conditional=MEDIA_SESSION
     26MediaSessionCoordinator conditional=MEDIA_SESSION_COORDINATOR
    2727MediaSource conditional=MEDIA_SOURCE
    2828MediaStream conditional=MEDIA_STREAM
  • trunk/Source/WebCore/page/Page.cpp

    r278253 r278336  
    34283428    auto* window = mainFrame().window();
    34293429    if (auto* navigator = window ? window->optionalNavigator() : nullptr)
    3430         NavigatorMediaSession::mediaSession(*navigator).createCoordinator(*m_mediaSessionCoordinator);
     3430        NavigatorMediaSession::mediaSession(*navigator).coordinator().setMediaSessionCoordinatorPrivate(*m_mediaSessionCoordinator);
    34313431}
    34323432
     
    34423442        return;
    34433443
    3444     auto* coordinator = NavigatorMediaSession::mediaSession(*navigator).coordinator();
    3445     if (!coordinator)
    3446         return;
    3447 
    3448     coordinator->close();
     3444    NavigatorMediaSession::mediaSession(*navigator).coordinator().close();
    34493445}
    34503446#endif
  • trunk/Source/WebCore/testing/Internals.cpp

    r278253 r278336  
    62476247    auto mock = MockMediaSessionCoordinator::create(context, WTFMove(listener));
    62486248    m_mockMediaSessionCoordinator = mock.ptr();
    6249     session.createCoordinator(WTFMove(mock));
     6249    session.coordinator().setMediaSessionCoordinatorPrivate(WTFMove(mock));
    62506250
    62516251    return { };
  • trunk/Tools/ChangeLog

    r278334 r278336  
     12021-06-01  Jean-Yves Avenard  <jya@apple.com>
     2
     3        MediaSession.coordinator should not be optional, relying on coordinator readyState change instead
     4        https://bugs.webkit.org/show_bug.cgi?id=226328
     5        rdar://77461335
     6
     7        Reviewed by Eric Carlson.
     8
     9        * TestWebKitAPI/Tests/WebKit/MediaSessionCoordinatorTest.mm:
     10        (TestWebKitAPI::MediaSessionCoordinatorTest::createCoordinator): Change test to match new API,
     11        using coordinatorstatechange event instead.
     12        * TestWebKitAPI/Tests/WebKitCocoa/media-remote.html:
     13
    1142021-06-01  Chris Fleizach  <cfleizach@apple.com>
    215
  • trunk/Tools/TestWebKitAPI/Tests/WebKit/MediaSessionCoordinatorTest.mm

    r278143 r278336  
    213213        TestWebKitAPI::Util::run(&done);
    214214
    215         listenForEventMessages({ "coordinatorchange"_s });
     215        listenForEventMessages({ "coordinatorstatechange"_s });
    216216
    217217        EXPECT_TRUE(result);
     
    219219            NSLog(@"-[_createMediaSessionCoordinatorForTesting:completionHandler:] failed!");
    220220
    221         waitForEventListenerToBeCalled("coordinatorchange"_s);
    222         ASSERT_TRUE(eventListenerWasCalled("coordinatorchange"_s));
     221        waitForEventListenerToBeCalled("coordinatorstatechange"_s);
     222        ASSERT_TRUE(eventListenerWasCalled("coordinatorstatechange"_s));
    223223    }
    224224
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/media-remote.html

    r275537 r278336  
    9797        }
    9898
    99         function postEvent(evt) 
     99        function postEvent(evt)
    100100        {
    101101            postMessage(`${evt.type} event`);
     
    136136            audio.addEventListener('pause', postEvent);
    137137            audio.addEventListener('seeked', postEvent);
    138             navigator.mediaSession.addEventListener('coordinatorchange', postEvent);
     138            navigator.mediaSession.coordinator.addEventListener('coordinatorstatechange', postEvent);
    139139        }, false);
    140140
Note: See TracChangeset for help on using the changeset viewer.