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) 29c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "bindings/core/v8/DOMWrapperWorld.h" 30197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptPromise.h" 31197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptPromiseResolver.h" 32197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ScriptState.h" 337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "core/dom/ExceptionCode.h" 34197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/events/Event.h" 3506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/GenericEventQueue.h" 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/MediaKeyError.h" 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/encryptedmedia/MediaKeyMessageEvent.h" 3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "modules/encryptedmedia/MediaKeys.h" 39197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "modules/encryptedmedia/SimpleContentDecryptionModuleResult.h" 40197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "platform/ContentDecryptionModuleResult.h" 417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/ContentType.h" 4209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/Logging.h" 437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/MIMETypeRegistry.h" 44197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "platform/Timer.h" 45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "public/platform/WebContentDecryptionModule.h" 46197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "public/platform/WebContentDecryptionModuleException.h" 47197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "public/platform/WebContentDecryptionModuleSession.h" 48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "public/platform/WebString.h" 49d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "public/platform/WebURL.h" 50c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "wtf/ArrayBuffer.h" 51c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "wtf/ArrayBufferView.h" 52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 53c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccistatic bool isKeySystemSupportedWithInitDataType(const String& keySystem, const String& initDataType) 567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(!keySystem.isEmpty()); 587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: initDataType != contentType. Implement this properly. 607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // http://crbug.com/385874. 617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci String contentType = initDataType; 627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (initDataType == "webm") { 637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci contentType = "video/webm"; 647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } else if (initDataType == "cenc") { 657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci contentType = "video/mp4"; 667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ContentType type(contentType); 697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return MIMETypeRegistry::isSupportedEncryptedMediaMIMEType(keySystem, type.type(), type.parameter("codecs")); 707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 72197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// A class holding a pending action. 73197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass MediaKeySession::PendingAction : public GarbageCollectedFinalized<MediaKeySession::PendingAction> { 74197021e6b966cfb06891637935ef33fff06433d1Ben Murdochpublic: 75197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch enum Type { 767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci GenerateRequest, 77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Update, 787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci Release 79197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch }; 80197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 81197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch Type type() const { return m_type; } 82e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) 83e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) const Persistent<ContentDecryptionModuleResult> result() const 84e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) { 85e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) return m_result; 86e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) } 87e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) 88e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) const RefPtr<ArrayBuffer> data() const 89e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) { 907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(m_type == GenerateRequest || m_type == Update); 91e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) return m_data; 92e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) } 93e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) 947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const String& initDataType() const 95e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) { 967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(m_type == GenerateRequest); 977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return m_initDataType; 98e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) } 99197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 1007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci static PendingAction* CreatePendingGenerateRequest(ContentDecryptionModuleResult* result, const String& initDataType, PassRefPtr<ArrayBuffer> initData) 101197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 102197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(result); 1037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(initData); 1047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return new PendingAction(GenerateRequest, result, initDataType, initData); 105197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 106197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 1077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci static PendingAction* CreatePendingUpdate(ContentDecryptionModuleResult* result, PassRefPtr<ArrayBuffer> data) 108197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 109197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(result); 1107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(data); 1117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return new PendingAction(Update, result, String(), data); 112197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 113197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci static PendingAction* CreatePendingRelease(ContentDecryptionModuleResult* result) 115e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) { 1167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(result); 1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return new PendingAction(Release, result, String(), PassRefPtr<ArrayBuffer>()); 118e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) } 119e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) 120197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ~PendingAction() 121197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 122197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 123197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 124197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch void trace(Visitor* visitor) 125197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 126197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_result); 127197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 128197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 129197021e6b966cfb06891637935ef33fff06433d1Ben Murdochprivate: 1307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci PendingAction(Type type, ContentDecryptionModuleResult* result, const String& initDataType, PassRefPtr<ArrayBuffer> data) 131197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch : m_type(type) 132197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch , m_result(result) 1337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_initDataType(initDataType) 134197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch , m_data(data) 135197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 136197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 137197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 138197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch const Type m_type; 139197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch const Member<ContentDecryptionModuleResult> m_result; 1407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci const String m_initDataType; 141c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) const RefPtr<ArrayBuffer> m_data; 142197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}; 143197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// This class wraps the promise resolver used when initializing a new session 1457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// and is passed to Chromium to fullfill the promise. This implementation of 1467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// completeWithSession() will resolve the promise with void, while 1477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// completeWithError() will reject the promise with an exception. complete() 1487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// is not expected to be called, and will reject the promise. 1497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass NewSessionResult : public ContentDecryptionModuleResult { 150197021e6b966cfb06891637935ef33fff06433d1Ben Murdochpublic: 1517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci NewSessionResult(ScriptState* scriptState, MediaKeySession* session) 1527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci : m_resolver(ScriptPromiseResolver::create(scriptState)) 1537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_session(session) 1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci { 1557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci WTF_LOG(Media, "NewSessionResult(%p)", this); 1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 157197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 1587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci virtual ~NewSessionResult() 159197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 1607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci WTF_LOG(Media, "~NewSessionResult(%p)", this); 161197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 162197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 163197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // ContentDecryptionModuleResult implementation. 164197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch virtual void complete() OVERRIDE 165197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 166197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT_NOT_REACHED(); 1677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci completeWithDOMException(InvalidStateError, "Unexpected completion."); 168197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 169197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 170e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) virtual void completeWithSession(WebContentDecryptionModuleResult::SessionStatus status) OVERRIDE 171197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 1727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (status != WebContentDecryptionModuleResult::NewSession) { 1737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT_NOT_REACHED(); 1747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci completeWithDOMException(InvalidStateError, "Unexpected completion."); 1757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 1767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 1777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_session->finishGenerateRequest(); 1787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver->resolve(); 1797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver.clear(); 180197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 181197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 1827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci virtual void completeWithError(WebContentDecryptionModuleException exceptionCode, unsigned long systemCode, const WebString& errorMessage) OVERRIDE 183197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch { 1847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci completeWithDOMException(WebCdmExceptionToExceptionCode(exceptionCode), errorMessage); 185197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 186197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 1877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // It is only valid to call this before completion. 1887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ScriptPromise promise() { return m_resolver->promise(); } 189197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 1907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci void trace(Visitor* visitor) 1917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci { 1927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci visitor->trace(m_session); 1937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ContentDecryptionModuleResult::trace(visitor); 194197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 195197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 1967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciprivate: 1977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Reject the promise with a DOMException. 1987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci void completeWithDOMException(ExceptionCode code, const String& errorMessage) 1997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci { 2007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver->reject(DOMException::create(code, errorMessage)); 2017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_resolver.clear(); 202197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 203d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 2047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RefPtr<ScriptPromiseResolver> m_resolver; 2057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci Member<MediaKeySession> m_session; 2067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}; 20709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 2087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciMediaKeySession* MediaKeySession::create(ScriptState* scriptState, MediaKeys* mediaKeys, const String& sessionType) 209926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 2107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RefPtrWillBeRawPtr<MediaKeySession> session = adoptRefCountedGarbageCollectedWillBeNoop(new MediaKeySession(scriptState, mediaKeys, sessionType)); 2117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci session->suspendIfNeeded(); 2127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return session.get(); 213926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciMediaKeySession::MediaKeySession(ScriptState* scriptState, MediaKeys* mediaKeys, const String& sessionType) 2167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci : ActiveDOMObject(scriptState->executionContext()) 2177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_keySystem(mediaKeys->keySystem()) 218f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) , m_asyncEventQueue(GenericEventQueue::create(this)) 2197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_mediaKeys(mediaKeys) 2207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_sessionType(sessionType) 2217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_isUninitialized(true) 2227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_isCallable(false) 223d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) , m_isClosed(false) 2247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci , m_closedPromise(new ClosedPromise(scriptState->executionContext(), this, ClosedPromise::Closed)) 225d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) , m_actionTimer(this, &MediaKeySession::actionTimerFired) 226926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 227197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_LOG(Media, "MediaKeySession(%p)::MediaKeySession", this); 2287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Create the matching Chromium object. It will not be usable until 2307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // initializeNewSession() is called in response to the user calling 2317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // generateRequest(). 2327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci WebContentDecryptionModule* cdm = mediaKeys->contentDecryptionModule(); 2337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_session = adoptPtr(cdm->createSession()); 234197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_session->setClientInterface(this); 235197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 2367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // MediaKeys::createSession(), step 2. 2377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 2.1 Let the sessionId attribute be the empty string. 2387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(sessionId().isEmpty()); 239197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 2407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 2.2 Let the expiration attribute be NaN. 2417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: Add expiration property. 2427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 2.3 Let the closed attribute be a new promise. 2447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(!closed(scriptState).isUndefinedOrNull()); 2457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 2.4 Let the session type be sessionType. 2477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(sessionType == m_sessionType); 2487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 2.5 Let uninitialized be true. 2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(m_isUninitialized); 251197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 2527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 2.6 Let callable be false. 2537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(!m_isCallable); 254926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 255926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 256926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)MediaKeySession::~MediaKeySession() 257926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 258197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_LOG(Media, "MediaKeySession(%p)::~MediaKeySession", this); 25909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_session.clear(); 2605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#if !ENABLE(OILPAN) 2615d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // MediaKeySession and m_asyncEventQueue always become unreachable 2625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // together. So MediaKeySession and m_asyncEventQueue are destructed in the 2635d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // same GC. We don't need to call cancelAllEvents explicitly in Oilpan. 26409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_asyncEventQueue->cancelAllEvents(); 2655d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#endif 266926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 267926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 268926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void MediaKeySession::setError(MediaKeyError* error) 269926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 270926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_error = error; 271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 272926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 273521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)String MediaKeySession::sessionId() const 274926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 275926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return m_session->sessionId(); 276926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 277926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 278c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)ScriptPromise MediaKeySession::closed(ScriptState* scriptState) 279c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 280c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return m_closedPromise->promise(scriptState->world()); 281c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 282c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 2837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciScriptPromise MediaKeySession::generateRequest(ScriptState* scriptState, const String& initDataType, ArrayBuffer* initData) 2847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 2857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RefPtr<ArrayBuffer> initDataCopy = ArrayBuffer::create(initData->data(), initData->byteLength()); 2867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return generateRequestInternal(scriptState, initDataType, initDataCopy.release()); 2877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 2887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciScriptPromise MediaKeySession::generateRequest(ScriptState* scriptState, const String& initDataType, ArrayBufferView* initData) 2907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 2917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci RefPtr<ArrayBuffer> initDataCopy = ArrayBuffer::create(initData->baseAddress(), initData->byteLength()); 2927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return generateRequestInternal(scriptState, initDataType, initDataCopy.release()); 2937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 2947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano TucciScriptPromise MediaKeySession::generateRequestInternal(ScriptState* scriptState, const String& initDataType, PassRefPtr<ArrayBuffer> initData) 2967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 2977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci WTF_LOG(Media, "MediaKeySession(%p)::generateRequest %s", this, initDataType.ascii().data()); 2987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 2997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // From https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html#dom-generaterequest: 3007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // The generateRequest(initDataType, initData) method creates a new session 3017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // for the specified initData. It must run the following steps: 3027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 1. If this object's uninitialized value is false, return a promise 3047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // rejected with a new DOMException whose name is "InvalidStateError". 3057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!m_isUninitialized) { 3067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return ScriptPromise::rejectWithDOMException( 3077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci scriptState, DOMException::create(InvalidStateError, "The session is already initialized.")); 3087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 3097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 2. Let this object's uninitialized be false. 3117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_isUninitialized = false; 3127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 3. If initDataType is an empty string, return a promise rejected with a 3147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // new DOMException whose name is "InvalidAccessError". 3157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (initDataType.isEmpty()) { 3167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return ScriptPromise::rejectWithDOMException( 3177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci scriptState, DOMException::create(InvalidAccessError, "The initDataType parameter is empty.")); 3187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 3197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 4. If initData is an empty array, return a promise rejected with a new 3217242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // DOMException whose name is"InvalidAccessError". 3227242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!initData->byteLength()) { 3237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return ScriptPromise::rejectWithDOMException( 3247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci scriptState, DOMException::create(InvalidAccessError, "The initData parameter is empty.")); 3257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 3267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 5. Let media keys be the MediaKeys object that created this object. 3287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // (Use m_mediaKey, which was set in the constructor.) 3297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 6. If the content decryption module corresponding to media keys's 3317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // keySystem attribute does not support initDataType as an initialization 3327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // data type, return a promise rejected with a new DOMException whose 3337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // name is "NotSupportedError". String comparison is case-sensitive. 3347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (!isKeySystemSupportedWithInitDataType(m_keySystem, initDataType)) { 3357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return ScriptPromise::rejectWithDOMException( 3367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci scriptState, DOMException::create(NotSupportedError, "The initialization data type '" + initDataType + "' is not supported by the key system.")); 3377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 3387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 7. Let init data be a copy of the contents of the initData parameter. 3407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // (Done before calling this method.) 3417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 8. Let session type be this object's session type. 3437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // (Done in constructor.) 3447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 9. Let promise be a new promise. 3467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci NewSessionResult* result = new NewSessionResult(scriptState, this); 3477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ScriptPromise promise = result->promise(); 3487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10. Run the following steps asynchronously (documented in 3507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // actionTimerFired()) 3517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_pendingActions.append(PendingAction::CreatePendingGenerateRequest(result, initDataType, initData)); 3527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(!m_actionTimer.isActive()); 3537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_actionTimer.startOneShot(0, FROM_HERE); 3547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 3557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 11. Return promise. 3567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci return promise; 3577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 3587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 359c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)ScriptPromise MediaKeySession::update(ScriptState* scriptState, ArrayBuffer* response) 360c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 361c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) RefPtr<ArrayBuffer> responseCopy = ArrayBuffer::create(response->data(), response->byteLength()); 362c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return updateInternal(scriptState, responseCopy.release()); 363c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 364c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 365c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)ScriptPromise MediaKeySession::update(ScriptState* scriptState, ArrayBufferView* response) 366c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 367c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) RefPtr<ArrayBuffer> responseCopy = ArrayBuffer::create(response->baseAddress(), response->byteLength()); 368c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return updateInternal(scriptState, responseCopy.release()); 369c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 370c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 371c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)ScriptPromise MediaKeySession::updateInternal(ScriptState* scriptState, PassRefPtr<ArrayBuffer> response) 372926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 373197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_LOG(Media, "MediaKeySession(%p)::update", this); 374d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(!m_isClosed); 37509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 37609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // From <https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html#dom-update>: 377197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // The update(response) method provides messages, including licenses, to the 378197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // CDM. It must run the following steps: 379197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 380197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 1. If response is an empty array, return a promise rejected with a new 381197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // DOMException whose name is "InvalidAccessError" and that has the 382197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // message "The response parameter is empty." 383c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (!response->byteLength()) { 384197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return ScriptPromise::rejectWithDOMException( 385197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch scriptState, DOMException::create(InvalidAccessError, "The response parameter is empty.")); 38609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 387926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 388197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 2. Let message be a copy of the contents of the response parameter. 389c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // (Copied in the caller.) 390926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 391197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 3. Let promise be a new promise. 392197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch SimpleContentDecryptionModuleResult* result = new SimpleContentDecryptionModuleResult(scriptState); 393197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ScriptPromise promise = result->promise(); 394926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 395197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 4. Run the following steps asynchronously (documented in 396197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // actionTimerFired()) 397c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_pendingActions.append(PendingAction::CreatePendingUpdate(result, response)); 398d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!m_actionTimer.isActive()) 399d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_actionTimer.startOneShot(0, FROM_HERE); 400197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 401197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 5. Return promise. 402197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return promise; 40309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 404926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 405197021e6b966cfb06891637935ef33fff06433d1Ben MurdochScriptPromise MediaKeySession::release(ScriptState* scriptState) 40609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 407197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_LOG(Media, "MediaKeySession(%p)::release", this); 408197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch SimpleContentDecryptionModuleResult* result = new SimpleContentDecryptionModuleResult(scriptState); 409197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ScriptPromise promise = result->promise(); 410197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 411197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // From <https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html#dom-close>: 412197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // The close() method allows an application to indicate that it no longer 413197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // needs the session and the CDM should release any resources associated 414197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // with this object and close it. The returned promise is resolved when the 415197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // request has been processed, and the closed attribute promise is resolved 416197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // when the session is closed. It must run the following steps: 417197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 418197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 1. If the Session Close algorithm has been run on this object, return a 419197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // promise fulfilled with undefined. 420197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (m_isClosed) { 421197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch result->complete(); 422197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return promise; 423197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 42409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 425197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 2. Let promise be a new promise. 426197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // (Created earlier so it was available in step 1.) 42709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 428197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 3. Run the following steps asynchronously (documented in 429197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // actionTimerFired()). 430197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_pendingActions.append(PendingAction::CreatePendingRelease(result)); 431d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!m_actionTimer.isActive()) 432d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_actionTimer.startOneShot(0, FROM_HERE); 433197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 434197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 4. Return promise. 435197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return promise; 436d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)} 437d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 438d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void MediaKeySession::actionTimerFired(Timer<MediaKeySession>*) 439d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){ 440d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(m_pendingActions.size()); 441d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 442197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Resolving promises now run synchronously and may result in additional 443197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // actions getting added to the queue. As a result, swap the queue to 444197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // a local copy to avoid problems if this happens. 445197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch HeapDeque<Member<PendingAction> > pendingActions; 446197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch pendingActions.swap(m_pendingActions); 447d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 448197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch while (!pendingActions.isEmpty()) { 449197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch PendingAction* action = pendingActions.takeFirst(); 450197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 451197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch switch (action->type()) { 4527242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci case PendingAction::GenerateRequest: 4537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: GenerateRequest", this); 4547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 4557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10.1 Let request be null. 4567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10.2 Let cdm be the CDM loaded during the initialization of 4577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // media keys. 4587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10.3 Use the cdm to execute the following steps: 4597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10.3.1 If the init data is not valid for initDataType, reject 4607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // promise with a new DOMException whose name is 4617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // "InvalidAccessError". 4627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10.3.2 If the init data is not supported by the cdm, reject 4637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // promise with a new DOMException whose name is 4647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // "NotSupportedError". 4657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10.3.3 Let request be a request (e.g. a license request) 4667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // generated based on the init data, which is interpreted 4677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // per initDataType, and session type. 4687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_session->initializeNewSession(action->initDataType(), static_cast<unsigned char*>(action->data()->data()), action->data()->byteLength(), m_sessionType, action->result()->result()); 4697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 4707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Remainder of steps executed in finishGenerateRequest(), called 4717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // when |result| is resolved. 4727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci break; 4737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 474d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) case PendingAction::Update: 475197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Update", this); 476197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // NOTE: Continued from step 4 of MediaKeySession::update(). 477197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Continue the update call by passing message to the cdm. Once 478197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // completed, it will resolve/reject the promise. 479c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_session->update(static_cast<unsigned char*>(action->data()->data()), action->data()->byteLength(), action->result()->result()); 480d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) break; 4817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 482d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) case PendingAction::Release: 483197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Release", this); 484197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // NOTE: Continued from step 3 of MediaKeySession::release(). 485197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 3.1 Let cdm be the cdm loaded in create(). 486197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 3.2 Use the cdm to execute the following steps: 487197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 3.2.1 Process the close request. Do not remove stored session data. 488197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 3.2.2 If the previous step caused the session to be closed, run the 489197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Session Close algorithm on this object. 490197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // 3.3 Resolve promise with undefined. 491197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_session->release(action->result()->result()); 492d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) break; 493d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 494926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 495926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 496926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 4977242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccivoid MediaKeySession::finishGenerateRequest() 4987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{ 4997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10.4 Set the sessionId attribute to a unique Session ID string. 5007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // It may be obtained from cdm. 5017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(!sessionId().isEmpty()); 5027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 5037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10.5 If any of the preceding steps failed, reject promise with a new 5047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // DOMException whose name is the appropriate error name. 5057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // (Done by call to completeWithError()). 5067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 5077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10.6 Add an entry for the value of the sessionId attribute to 5087242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // media keys's list of active session IDs. 5097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // FIXME: Is this required? 5107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // https://www.w3.org/Bugs/Public/show_bug.cgi?id=26758 5117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 5127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10.7 Run the Queue a "message" Event algorithm on the session, 5137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // providing request and null. 5147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // (Done by the CDM). 5157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 5167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // 10.8 Let this object's callable be true. 5177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_isCallable = true; 5187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci} 5197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 5207242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// Queue a task to fire a simple event named keymessage at the new object. 521e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void MediaKeySession::message(const unsigned char* message, size_t messageLength, const WebURL& destinationURL) 522926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 523197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_LOG(Media, "MediaKeySession(%p)::message", this); 52409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 5257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci // Verify that 'message' not fired before session initialization is complete. 5267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci ASSERT(m_isCallable); 5277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci 52809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) MediaKeyMessageEventInit init; 52909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) init.bubbles = false; 53009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) init.cancelable = false; 531c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) init.message = ArrayBuffer::create(static_cast<const void*>(message), messageLength); 532d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) init.destinationURL = destinationURL.string(); 533926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 534a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch RefPtrWillBeRawPtr<MediaKeyMessageEvent> event = MediaKeyMessageEvent::create(EventTypeNames::message, init); 53509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) event->setTarget(this); 53609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_asyncEventQueue->enqueueEvent(event.release()); 537926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 538926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 53909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void MediaKeySession::ready() 540926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 541197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_LOG(Media, "MediaKeySession(%p)::ready", this); 542926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 543a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::ready); 54409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) event->setTarget(this); 54509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_asyncEventQueue->enqueueEvent(event.release()); 546521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 547521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 54809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void MediaKeySession::close() 549521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 550197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_LOG(Media, "MediaKeySession(%p)::close", this); 551d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 552d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Once closed, the session can no longer be the target of events from 553d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // the CDM so this object can be garbage collected. 554d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_isClosed = true; 555197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 556c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // Resolve the closed promise. 557c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) m_closedPromise->resolve(V8UndefinedType()); 558521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 559521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 560521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)// Queue a task to fire a simple event named keyadded at the MediaKeySession object. 56109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void MediaKeySession::error(MediaKeyErrorCode errorCode, unsigned long systemCode) 562521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 563197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_LOG(Media, "MediaKeySession(%p)::error: errorCode=%d, systemCode=%lu", this, errorCode, systemCode); 56409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 565521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) MediaKeyError::Code mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN; 566521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) switch (errorCode) { 567d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) case MediaKeyErrorCodeUnknown: 568521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN; 569521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) break; 570d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) case MediaKeyErrorCodeClient: 571521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_CLIENT; 572521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) break; 573926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 574521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 575521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 1. Create a new MediaKeyError object with the following attributes: 576521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // code = the appropriate MediaKeyError code 577521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // systemCode = a Key System-specific value, if provided, and 0 otherwise 578521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 2. Set the MediaKeySession object's error attribute to the error object created in the previous step. 579521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_error = MediaKeyError::create(mediaKeyErrorCode, systemCode); 580521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 581521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) // 3. queue a task to fire a simple event named keyerror at the MediaKeySession object. 582a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::error); 583521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) event->setTarget(this); 584521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) m_asyncEventQueue->enqueueEvent(event.release()); 585521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)} 586521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 587e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void MediaKeySession::error(WebContentDecryptionModuleException exception, unsigned long systemCode, const WebString& errorMessage) 58876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles){ 58976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) WTF_LOG(Media, "MediaKeySession::error: exception=%d, systemCode=%lu", exception, systemCode); 59076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) 59176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) // FIXME: EME-WD MediaKeyError now derives from DOMException. Figure out how 59276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) // to implement this without breaking prefixed EME, which has a totally 59376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) // different definition. The spec may also change to be just a DOMException. 59476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) // For now, simply generate an existing MediaKeyError. 59576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) MediaKeyErrorCode errorCode; 59676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) switch (exception) { 597e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) case WebContentDecryptionModuleExceptionClientError: 59876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) errorCode = MediaKeyErrorCodeClient; 59976c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) break; 60076c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) default: 60176c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) // All other exceptions get converted into Unknown. 60276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) errorCode = MediaKeyErrorCodeUnknown; 60376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) break; 60476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) } 60576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) error(errorCode, systemCode); 60676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)} 60776c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles) 60809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)const AtomicString& MediaKeySession::interfaceName() const 609521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles){ 61009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return EventTargetNames::MediaKeySession; 61109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 612521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 61309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)ExecutionContext* MediaKeySession::executionContext() const 61409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 61509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return ActiveDOMObject::executionContext(); 616926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 617926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 61809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool MediaKeySession::hasPendingActivity() const 619926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 620d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Remain around if there are pending events or MediaKeys is still around 621d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // and we're not closed. 622197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch WTF_LOG(Media, "MediaKeySession(%p)::hasPendingActivity %s%s%s%s", this, 623197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ActiveDOMObject::hasPendingActivity() ? " ActiveDOMObject::hasPendingActivity()" : "", 624197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch !m_pendingActions.isEmpty() ? " !m_pendingActions.isEmpty()" : "", 625197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_asyncEventQueue->hasPendingEvents() ? " m_asyncEventQueue->hasPendingEvents()" : "", 6267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci (m_mediaKeys && !m_isClosed) ? " m_mediaKeys && !m_isClosed" : ""); 627197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 62809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return ActiveDOMObject::hasPendingActivity() 629d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || !m_pendingActions.isEmpty() 630d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) || m_asyncEventQueue->hasPendingEvents() 6317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci || (m_mediaKeys && !m_isClosed); 632926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 633926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 63409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void MediaKeySession::stop() 635926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 636d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Stop the CDM from firing any more events for this session. 637d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_session.clear(); 638d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_isClosed = true; 639d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 640d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (m_actionTimer.isActive()) 641d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_actionTimer.stop(); 642d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_pendingActions.clear(); 64309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_asyncEventQueue->close(); 644926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 645926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 646f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuvoid MediaKeySession::trace(Visitor* visitor) 647f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu{ 648197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_error); 6495d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) visitor->trace(m_asyncEventQueue); 650197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch visitor->trace(m_pendingActions); 6517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci visitor->trace(m_mediaKeys); 652c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) visitor->trace(m_closedPromise); 653d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) EventTargetWithInlineData::trace(visitor); 654f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu} 655f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu 656e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)} // namespace blink 657