1926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/*
2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2013 Apple Inc. All rights reserved.
3926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * modification, are permitted provided that the following conditions
6926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * are met:
7926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
8926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
9926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
10926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
11926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *    documentation and/or other materials provided with the distribution.
12926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
13926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THE POSSIBILITY OF SUCH DAMAGE.
24926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */
25926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
26926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include "config.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/encryptedmedia/MediaKeySession.h"
28926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "bindings/v8/ExceptionState.h"
307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "core/dom/ExceptionCode.h"
3106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/GenericEventQueue.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/MediaKeyError.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/encryptedmedia/MediaKeyMessageEvent.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/encryptedmedia/MediaKeys.h"
3509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/Logging.h"
36d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "public/platform/WebContentDecryptionModule.h"
37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "public/platform/WebString.h"
38d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "public/platform/WebURL.h"
39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)namespace WebCore {
41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassOwnPtr<MediaKeySession::PendingAction> MediaKeySession::PendingAction::CreatePendingUpdate(PassRefPtr<Uint8Array> data)
43d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
44d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(data);
45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return adoptPtr(new PendingAction(Update, data));
46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
47d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassOwnPtr<MediaKeySession::PendingAction> MediaKeySession::PendingAction::CreatePendingRelease()
49d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return adoptPtr(new PendingAction(Release, PassRefPtr<Uint8Array>()));
51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
53d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)MediaKeySession::PendingAction::PendingAction(Type type, PassRefPtr<Uint8Array> data)
54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    : type(type)
55d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , data(data)
56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
57d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)MediaKeySession::PendingAction::~PendingAction()
60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
63f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)MediaKeySession* MediaKeySession::create(ExecutionContext* context, blink::WebContentDecryptionModule* cdm, MediaKeys* keys)
64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
655d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    MediaKeySession* session = adoptRefCountedGarbageCollectedWillBeNoop(new MediaKeySession(context, cdm, keys));
6609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    session->suspendIfNeeded();
67f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    return session;
68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
70f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)MediaKeySession::MediaKeySession(ExecutionContext* context, blink::WebContentDecryptionModule* cdm, MediaKeys* keys)
7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    : ActiveDOMObject(context)
72521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    , m_keySystem(keys->keySystem())
73f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    , m_asyncEventQueue(GenericEventQueue::create(this))
74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_session(adoptPtr(cdm->createSession(this)))
75521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    , m_keys(keys)
76d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_isClosed(false)
77d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_actionTimer(this, &MediaKeySession::actionTimerFired)
78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
7909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    WTF_LOG(Media, "MediaKeySession::MediaKeySession");
805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ScriptWrappable::init(this);
8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(m_session);
82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)MediaKeySession::~MediaKeySession()
85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_session.clear();
875d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#if !ENABLE(OILPAN)
885d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // MediaKeySession and m_asyncEventQueue always become unreachable
895d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // together. So MediaKeySession and m_asyncEventQueue are destructed in the
905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    // same GC. We don't need to call cancelAllEvents explicitly in Oilpan.
9109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_asyncEventQueue->cancelAllEvents();
925d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#endif
93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void MediaKeySession::setError(MediaKeyError* error)
96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    m_error = error;
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
100521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)String MediaKeySession::sessionId() const
101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return m_session->sessionId();
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void MediaKeySession::initializeNewSession(const String& mimeType, const Uint8Array& initData)
106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
107d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(!m_isClosed);
108d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_session->initializeNewSession(mimeType, initData.data(), initData.length());
109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void MediaKeySession::update(Uint8Array* response, ExceptionState& exceptionState)
112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
11309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    WTF_LOG(Media, "MediaKeySession::update");
114d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(!m_isClosed);
11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // From <https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html#dom-update>:
11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // The update(response) method must run the following steps:
11810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    // 1. If response is an empty array, throw an INVALID_ACCESS_ERR
119d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    //    exception and abort these steps.
12010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    if (!response->length()) {
12109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        exceptionState.throwDOMException(InvalidAccessError, String::format("The response argument provided is %s.", response ? "an empty array" : "invalid"));
122926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return;
12309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // 2. If the session is not in the PENDING state, throw an INVALID_STATE_ERR.
12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // FIXME: Implement states in MediaKeySession.
127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // 3. Schedule a task to handle the call, providing response.
129d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_pendingActions.append(PendingAction::CreatePendingUpdate(response));
130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
131d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!m_actionTimer.isActive())
132d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_actionTimer.startOneShot(0, FROM_HERE);
13309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
135d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void MediaKeySession::release(ExceptionState& exceptionState)
13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    WTF_LOG(Media, "MediaKeySession::release");
138d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(!m_isClosed);
139d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // From <https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html#dom-release>:
141d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // The release() method must run the following steps:
142d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // 1. If the state of the MediaKeySession is CLOSED then abort these steps.
143d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // 2. If the state of the MediaKeySession is ERROR, throw an INVALID_STATE_ERR
144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    //    exception and abort these steps.
145d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // FIXME: Implement states in MediaKeySession.
14609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
147d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // 3. Schedule a task to handle the call.
148d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_pendingActions.append(PendingAction::CreatePendingRelease());
14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
150d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!m_actionTimer.isActive())
151d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_actionTimer.startOneShot(0, FROM_HERE);
152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
153d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
154d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void MediaKeySession::actionTimerFired(Timer<MediaKeySession>*)
155d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
156d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(m_pendingActions.size());
157d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
158d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    while (!m_pendingActions.isEmpty()) {
159d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        OwnPtr<PendingAction> pendingAction(m_pendingActions.takeFirst());
160d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
161d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        switch (pendingAction->type) {
162d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        case PendingAction::Update:
163d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // NOTE: Continued from step 3. of MediaKeySession::update()
164d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // 3.1. Let cdm be the cdm loaded in the MediaKeys constructor.
165d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // 3.2. Let request be null.
166d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // 3.3. Use cdm to execute the following steps:
167d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // 3.3.1 Process response.
168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            m_session->update(pendingAction->data->data(), pendingAction->data->length());
169d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            break;
170d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        case PendingAction::Release:
171d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // NOTE: Continued from step 3. of MediaKeySession::release().
172d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // 3.1 Let cdm be the cdm loaded in the MediaKeys constructor.
173d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // 3.2 Use cdm to execute the following steps:
174d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // 3.2.1 Process the release request.
175d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            m_session->release();
176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            break;
177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
18109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Queue a task to fire a simple event named keymessage at the new object
182d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void MediaKeySession::message(const unsigned char* message, size_t messageLength, const blink::WebURL& destinationURL)
183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
18409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    WTF_LOG(Media, "MediaKeySession::message");
18509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
18609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    MediaKeyMessageEventInit init;
18709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    init.bubbles = false;
18809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    init.cancelable = false;
18909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    init.message = Uint8Array::create(message, messageLength);
190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    init.destinationURL = destinationURL.string();
191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
192a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    RefPtrWillBeRawPtr<MediaKeyMessageEvent> event = MediaKeyMessageEvent::create(EventTypeNames::message, init);
19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    event->setTarget(this);
19409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_asyncEventQueue->enqueueEvent(event.release());
195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
19709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void MediaKeySession::ready()
198926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
19909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    WTF_LOG(Media, "MediaKeySession::ready");
200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
201a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::ready);
20209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    event->setTarget(this);
20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_asyncEventQueue->enqueueEvent(event.release());
204521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
205521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
20609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void MediaKeySession::close()
207521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
20809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    WTF_LOG(Media, "MediaKeySession::close");
20909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
210a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::close);
211521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    event->setTarget(this);
212521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_asyncEventQueue->enqueueEvent(event.release());
213d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
214d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Once closed, the session can no longer be the target of events from
215d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // the CDM so this object can be garbage collected.
216d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_isClosed = true;
217521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
218521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
219521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)// Queue a task to fire a simple event named keyadded at the MediaKeySession object.
22009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void MediaKeySession::error(MediaKeyErrorCode errorCode, unsigned long systemCode)
221521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
22209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    WTF_LOG(Media, "MediaKeySession::error: errorCode=%d, systemCode=%lu", errorCode, systemCode);
22309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
224521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    MediaKeyError::Code mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
225521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    switch (errorCode) {
226d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    case MediaKeyErrorCodeUnknown:
227521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
228521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        break;
229d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    case MediaKeyErrorCodeClient:
230521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_CLIENT;
231521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)        break;
232926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
233521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
234521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 1. Create a new MediaKeyError object with the following attributes:
235521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    //    code = the appropriate MediaKeyError code
236521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    //    systemCode = a Key System-specific value, if provided, and 0 otherwise
237521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 2. Set the MediaKeySession object's error attribute to the error object created in the previous step.
238521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_error = MediaKeyError::create(mediaKeyErrorCode, systemCode);
239521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
240521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    // 3. queue a task to fire a simple event named keyerror at the MediaKeySession object.
241a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::error);
242521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    event->setTarget(this);
243521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    m_asyncEventQueue->enqueueEvent(event.release());
244521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)}
245521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
24676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)void MediaKeySession::error(blink::WebContentDecryptionModuleException exception, unsigned long systemCode, const blink::WebString& errorMessage)
24776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles){
24876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    WTF_LOG(Media, "MediaKeySession::error: exception=%d, systemCode=%lu", exception, systemCode);
24976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)
25076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // FIXME: EME-WD MediaKeyError now derives from DOMException. Figure out how
25176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // to implement this without breaking prefixed EME, which has a totally
25276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // different definition. The spec may also change to be just a DOMException.
25376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    // For now, simply generate an existing MediaKeyError.
25476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    MediaKeyErrorCode errorCode;
25576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    switch (exception) {
25676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    case blink::WebContentDecryptionModuleExceptionClientError:
25776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        errorCode = MediaKeyErrorCodeClient;
25876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        break;
25976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    default:
26076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        // All other exceptions get converted into Unknown.
26176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        errorCode = MediaKeyErrorCodeUnknown;
26276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        break;
26376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    }
26476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    error(errorCode, systemCode);
26576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)}
26676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)
26709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)const AtomicString& MediaKeySession::interfaceName() const
268521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){
26909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return EventTargetNames::MediaKeySession;
27009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
271521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
27209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)ExecutionContext* MediaKeySession::executionContext() const
27309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
27409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return ActiveDOMObject::executionContext();
275926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
276926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
27709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool MediaKeySession::hasPendingActivity() const
278926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
279d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Remain around if there are pending events or MediaKeys is still around
280d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // and we're not closed.
28109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return ActiveDOMObject::hasPendingActivity()
282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        || !m_pendingActions.isEmpty()
283d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        || m_asyncEventQueue->hasPendingEvents()
284d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        || (m_keys && !m_isClosed);
285926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
286926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
28709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void MediaKeySession::stop()
288926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
289d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Stop the CDM from firing any more events for this session.
290d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_session.clear();
291d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_isClosed = true;
292d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
293d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_actionTimer.isActive())
294d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_actionTimer.stop();
295d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_pendingActions.clear();
29609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_asyncEventQueue->close();
297926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
298926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
299f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuvoid MediaKeySession::trace(Visitor* visitor)
300f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{
3015d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    visitor->trace(m_asyncEventQueue);
302f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    visitor->trace(m_keys);
303d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    EventTargetWithInlineData::trace(visitor);
304f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu}
305f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu
306926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
307