| Index: Source/modules/encryptedmedia/MediaKeySession.cpp
|
| diff --git a/Source/modules/encryptedmedia/MediaKeySession.cpp b/Source/modules/encryptedmedia/MediaKeySession.cpp
|
| index a112469acaaff06f1dd219d2ffa941afee20db10..927694730054c8646ef3bf5a1ea8135452557af2 100644
|
| --- a/Source/modules/encryptedmedia/MediaKeySession.cpp
|
| +++ b/Source/modules/encryptedmedia/MediaKeySession.cpp
|
| @@ -55,13 +55,29 @@ class MediaKeySession::PendingAction : public GarbageCollectedFinalized<MediaKey
|
| public:
|
| enum Type {
|
| Update,
|
| - Release
|
| + Release,
|
| + Message
|
| };
|
|
|
| Type type() const { return m_type; }
|
| - const Persistent<ContentDecryptionModuleResult> result() const { return m_result; }
|
| - // |data| is only valid for Update types.
|
| - const RefPtr<ArrayBuffer> data() const { return m_data; }
|
| +
|
| + const Persistent<ContentDecryptionModuleResult> result() const
|
| + {
|
| + ASSERT(m_type == Update || m_type == Release);
|
| + return m_result;
|
| + }
|
| +
|
| + const RefPtr<ArrayBuffer> data() const
|
| + {
|
| + ASSERT(m_type == Update);
|
| + return m_data;
|
| + }
|
| +
|
| + RefPtrWillBeRawPtr<Event> event()
|
| + {
|
| + ASSERT(m_type == Message);
|
| + return m_event;
|
| + }
|
|
|
| static PendingAction* CreatePendingUpdate(ContentDecryptionModuleResult* result, PassRefPtr<ArrayBuffer> data)
|
| {
|
| @@ -76,6 +92,12 @@ public:
|
| return new PendingAction(Release, result, PassRefPtr<ArrayBuffer>());
|
| }
|
|
|
| + static PendingAction* CreatePendingMessage(PassRefPtrWillBeRawPtr<Event> event)
|
| + {
|
| + ASSERT(event);
|
| + return new PendingAction(Message, event);
|
| + }
|
| +
|
| ~PendingAction()
|
| {
|
| }
|
| @@ -93,9 +115,16 @@ private:
|
| {
|
| }
|
|
|
| + PendingAction(Type type, PassRefPtrWillBeRawPtr<Event> event)
|
| + : m_type(type)
|
| + , m_event(event)
|
| + {
|
| + }
|
| +
|
| const Type m_type;
|
| const Member<ContentDecryptionModuleResult> m_result;
|
| const RefPtr<ArrayBuffer> m_data;
|
| + const RefPtrWillBeRawPtr<Event> m_event;
|
| };
|
|
|
| // This class allows a MediaKeySession object to be created asynchronously.
|
| @@ -444,6 +473,10 @@ void MediaKeySession::actionTimerFired(Timer<MediaKeySession>*)
|
| // 3.3 Resolve promise with undefined.
|
| m_session->release(action->result()->result());
|
| break;
|
| + case PendingAction::Message:
|
| + WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Message", this);
|
| + m_asyncEventQueue->enqueueEvent(action->event().release());
|
| + break;
|
| }
|
| }
|
| }
|
| @@ -461,6 +494,21 @@ void MediaKeySession::message(const unsigned char* message, size_t messageLength
|
|
|
| RefPtrWillBeRawPtr<MediaKeyMessageEvent> event = MediaKeyMessageEvent::create(EventTypeNames::message, init);
|
| event->setTarget(this);
|
| +
|
| + if (!hasEventListeners()) {
|
| + // Since this event may be generated immediately after resolving the
|
| + // CreateSession() promise, it is possible that the JavaScript hasn't
|
| + // had time to run the .then() action and bind any necessary event
|
| + // handlers. If there are no event handlers connected, delay enqueuing
|
| + // this message to provide time for the JavaScript to run. This will
|
| + // also affect the (rare) case where there is no message handler
|
| + // attched during normal operation.
|
| + m_pendingActions.append(PendingAction::CreatePendingMessage(event.release()));
|
| + if (!m_actionTimer.isActive())
|
| + m_actionTimer.startOneShot(0, FROM_HERE);
|
| + return;
|
| + }
|
| +
|
| m_asyncEventQueue->enqueueEvent(event.release());
|
| }
|
|
|
|
|