This source file includes following definitions.
- CreatePendingUpdate
- CreatePendingRelease
- data
- create
- m_actionTimer
- setError
- sessionId
- initializeNewSession
- update
- release
- actionTimerFired
- message
- ready
- close
- error
- interfaceName
- executionContext
- hasPendingActivity
- stop
#include "config.h"
#include "modules/encryptedmedia/MediaKeySession.h"
#include "bindings/v8/ExceptionState.h"
#include "core/events/Event.h"
#include "core/dom/ExceptionCode.h"
#include "core/events/GenericEventQueue.h"
#include "core/html/MediaKeyError.h"
#include "modules/encryptedmedia/MediaKeyMessageEvent.h"
#include "modules/encryptedmedia/MediaKeys.h"
#include "platform/Logging.h"
#include "public/platform/WebContentDecryptionModule.h"
#include "public/platform/WebString.h"
#include "public/platform/WebURL.h"
namespace WebCore {
PassOwnPtr<MediaKeySession::PendingAction> MediaKeySession::PendingAction::CreatePendingUpdate(PassRefPtr<Uint8Array> data)
{
ASSERT(data);
return adoptPtr(new PendingAction(Update, data));
}
PassOwnPtr<MediaKeySession::PendingAction> MediaKeySession::PendingAction::CreatePendingRelease()
{
return adoptPtr(new PendingAction(Release, PassRefPtr<Uint8Array>()));
}
MediaKeySession::PendingAction::PendingAction(Type type, PassRefPtr<Uint8Array> data)
: type(type)
, data(data)
{
}
MediaKeySession::PendingAction::~PendingAction()
{
}
PassRefPtrWillBeRawPtr<MediaKeySession> MediaKeySession::create(ExecutionContext* context, blink::WebContentDecryptionModule* cdm, WeakPtr<MediaKeys> keys)
{
RefPtrWillBeRawPtr<MediaKeySession> session(adoptRefWillBeRefCountedGarbageCollected(new MediaKeySession(context, cdm, keys)));
session->suspendIfNeeded();
return session.release();
}
MediaKeySession::MediaKeySession(ExecutionContext* context, blink::WebContentDecryptionModule* cdm, WeakPtr<MediaKeys> keys)
: ActiveDOMObject(context)
, m_keySystem(keys->keySystem())
, m_asyncEventQueue(GenericEventQueue::create(this))
, m_session(adoptPtr(cdm->createSession(this)))
, m_keys(keys)
, m_isClosed(false)
, m_actionTimer(this, &MediaKeySession::actionTimerFired)
{
WTF_LOG(Media, "MediaKeySession::MediaKeySession");
ScriptWrappable::init(this);
ASSERT(m_session);
}
MediaKeySession::~MediaKeySession()
{
m_session.clear();
m_asyncEventQueue->cancelAllEvents();
}
void MediaKeySession::setError(MediaKeyError* error)
{
m_error = error;
}
String MediaKeySession::sessionId() const
{
return m_session->sessionId();
}
void MediaKeySession::initializeNewSession(const String& mimeType, const Uint8Array& initData)
{
ASSERT(!m_isClosed);
m_session->initializeNewSession(mimeType, initData.data(), initData.length());
}
void MediaKeySession::update(Uint8Array* response, ExceptionState& exceptionState)
{
WTF_LOG(Media, "MediaKeySession::update");
ASSERT(!m_isClosed);
if (!response || !response->length()) {
exceptionState.throwDOMException(InvalidAccessError, String::format("The response argument provided is %s.", response ? "an empty array" : "invalid"));
return;
}
m_pendingActions.append(PendingAction::CreatePendingUpdate(response));
if (!m_actionTimer.isActive())
m_actionTimer.startOneShot(0, FROM_HERE);
}
void MediaKeySession::release(ExceptionState& exceptionState)
{
WTF_LOG(Media, "MediaKeySession::release");
ASSERT(!m_isClosed);
m_pendingActions.append(PendingAction::CreatePendingRelease());
if (!m_actionTimer.isActive())
m_actionTimer.startOneShot(0, FROM_HERE);
}
void MediaKeySession::actionTimerFired(Timer<MediaKeySession>*)
{
ASSERT(m_pendingActions.size());
while (!m_pendingActions.isEmpty()) {
OwnPtr<PendingAction> pendingAction(m_pendingActions.takeFirst());
switch (pendingAction->type) {
case PendingAction::Update:
m_session->update(pendingAction->data->data(), pendingAction->data->length());
break;
case PendingAction::Release:
m_session->release();
break;
}
}
}
void MediaKeySession::message(const unsigned char* message, size_t messageLength, const blink::WebURL& destinationURL)
{
WTF_LOG(Media, "MediaKeySession::message");
MediaKeyMessageEventInit init;
init.bubbles = false;
init.cancelable = false;
init.message = Uint8Array::create(message, messageLength);
init.destinationURL = destinationURL.string();
RefPtrWillBeRawPtr<MediaKeyMessageEvent> event = MediaKeyMessageEvent::create(EventTypeNames::message, init);
event->setTarget(this);
m_asyncEventQueue->enqueueEvent(event.release());
}
void MediaKeySession::ready()
{
WTF_LOG(Media, "MediaKeySession::ready");
RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::ready);
event->setTarget(this);
m_asyncEventQueue->enqueueEvent(event.release());
}
void MediaKeySession::close()
{
WTF_LOG(Media, "MediaKeySession::close");
RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::close);
event->setTarget(this);
m_asyncEventQueue->enqueueEvent(event.release());
m_isClosed = true;
}
void MediaKeySession::error(MediaKeyErrorCode errorCode, unsigned long systemCode)
{
WTF_LOG(Media, "MediaKeySession::error: errorCode=%d, systemCode=%lu", errorCode, systemCode);
MediaKeyError::Code mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
switch (errorCode) {
case MediaKeyErrorCodeUnknown:
mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
break;
case MediaKeyErrorCodeClient:
mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_CLIENT;
break;
}
m_error = MediaKeyError::create(mediaKeyErrorCode, systemCode);
RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::error);
event->setTarget(this);
m_asyncEventQueue->enqueueEvent(event.release());
}
const AtomicString& MediaKeySession::interfaceName() const
{
return EventTargetNames::MediaKeySession;
}
ExecutionContext* MediaKeySession::executionContext() const
{
return ActiveDOMObject::executionContext();
}
bool MediaKeySession::hasPendingActivity() const
{
return ActiveDOMObject::hasPendingActivity()
|| !m_pendingActions.isEmpty()
|| m_asyncEventQueue->hasPendingEvents()
|| (m_keys && !m_isClosed);
}
void MediaKeySession::stop()
{
m_session.clear();
m_isClosed = true;
if (m_actionTimer.isActive())
m_actionTimer.stop();
m_pendingActions.clear();
m_asyncEventQueue->close();
}
}