Chromium Code Reviews| Index: Source/modules/encryptedmedia/MediaKeySession.cpp |
| diff --git a/Source/modules/encryptedmedia/MediaKeySession.cpp b/Source/modules/encryptedmedia/MediaKeySession.cpp |
| index a112469acaaff06f1dd219d2ffa941afee20db10..edbf49189022d28ca8f9f56d83df5ee5bdbed7cc 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()); |
|
ddorwin
2014/08/12 22:31:45
Won't ".release()" this fail to compile with Oilpa
jrummell
2014/08/12 23:12:43
With Oilpan there is a RawPtr class that has all t
|
| + break; |
| } |
| } |
| } |
| @@ -461,6 +494,19 @@ 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. |
|
ddorwin
2014/08/12 22:31:45
Is this guaranteed to be allow sufficient time for
jrummell
2014/08/12 23:12:43
For testing I added DCHECK(hasEventListeners()) in
|
| + m_pendingActions.append(PendingAction::CreatePendingMessage(event.release())); |
| + if (!m_actionTimer.isActive()) |
| + m_actionTimer.startOneShot(0, FROM_HERE); |
| + return; |
| + } |
| + |
| m_asyncEventQueue->enqueueEvent(event.release()); |
| } |