Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(366)

Side by Side Diff: Source/modules/encryptedmedia/MediaKeySession.cpp

Issue 641433002: Implement MediaKeySession.load() (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: initialize variable for Windows Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Apple Inc. All rights reserved. 2 * Copyright (C) 2013 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 29 matching lines...) Expand all
40 #include "platform/ContentDecryptionModuleResult.h" 40 #include "platform/ContentDecryptionModuleResult.h"
41 #include "platform/ContentType.h" 41 #include "platform/ContentType.h"
42 #include "platform/Logging.h" 42 #include "platform/Logging.h"
43 #include "platform/MIMETypeRegistry.h" 43 #include "platform/MIMETypeRegistry.h"
44 #include "platform/Timer.h" 44 #include "platform/Timer.h"
45 #include "public/platform/WebContentDecryptionModule.h" 45 #include "public/platform/WebContentDecryptionModule.h"
46 #include "public/platform/WebContentDecryptionModuleException.h" 46 #include "public/platform/WebContentDecryptionModuleException.h"
47 #include "public/platform/WebContentDecryptionModuleSession.h" 47 #include "public/platform/WebContentDecryptionModuleSession.h"
48 #include "public/platform/WebString.h" 48 #include "public/platform/WebString.h"
49 #include "public/platform/WebURL.h" 49 #include "public/platform/WebURL.h"
50 #include "wtf/ASCIICType.h"
50 #include "wtf/ArrayBuffer.h" 51 #include "wtf/ArrayBuffer.h"
51 #include "wtf/ArrayBufferView.h" 52 #include "wtf/ArrayBufferView.h"
52 #include <cmath> 53 #include <cmath>
53 #include <limits> 54 #include <limits>
54 55
55 namespace { 56 namespace {
56 57
57 // The list of possible values for |sessionType| passed to createSession(). 58 // The list of possible values for |sessionType|.
58 #if ENABLE(ASSERT)
59 const char* kTemporary = "temporary"; 59 const char* kTemporary = "temporary";
60 #endif
61 const char* kPersistent = "persistent"; 60 const char* kPersistent = "persistent";
62 61
62 // Minimum and maximum length for session ids.
63 enum {
64 MinSessionIdLength = 1,
65 MaxSessionIdLength = 512
66 };
67
63 } // namespace 68 } // namespace
64 69
65 namespace blink { 70 namespace blink {
66 71
67 static bool isKeySystemSupportedWithInitDataType(const String& keySystem, const String& initDataType) 72 static bool isKeySystemSupportedWithInitDataType(const String& keySystem, const String& initDataType)
68 { 73 {
69 ASSERT(!keySystem.isEmpty()); 74 ASSERT(!keySystem.isEmpty());
70 75
71 // FIXME: initDataType != contentType. Implement this properly. 76 // FIXME: initDataType != contentType. Implement this properly.
72 // http://crbug.com/385874. 77 // http://crbug.com/385874.
73 String contentType = initDataType; 78 String contentType = initDataType;
74 if (initDataType == "webm") { 79 if (initDataType == "webm") {
75 contentType = "video/webm"; 80 contentType = "video/webm";
76 } else if (initDataType == "cenc") { 81 } else if (initDataType == "cenc") {
77 contentType = "video/mp4"; 82 contentType = "video/mp4";
78 } 83 }
79 84
80 ContentType type(contentType); 85 ContentType type(contentType);
81 return MIMETypeRegistry::isSupportedEncryptedMediaMIMEType(keySystem, type.t ype(), type.parameter("codecs")); 86 return MIMETypeRegistry::isSupportedEncryptedMediaMIMEType(keySystem, type.t ype(), type.parameter("codecs"));
82 } 87 }
83 88
89 // Checks that |sessionId| looks correct and returns whether all checks pass.
90 static bool isValidSessionId(const String& sessionId)
91 {
92 if ((sessionId.length() < MinSessionIdLength) || (sessionId.length() > MaxSe ssionIdLength))
93 return false;
94
95 if (!sessionId.containsOnlyASCII())
96 return false;
97
98 // Check that the sessionId only contains alphanumeric characters.
99 for (unsigned i = 0; i < sessionId.length(); ++i) {
100 if (!isASCIIAlphanumeric(sessionId[i]))
101 return false;
102 }
103
104 return true;
105 }
106
84 // A class holding a pending action. 107 // A class holding a pending action.
85 class MediaKeySession::PendingAction : public GarbageCollectedFinalized<MediaKey Session::PendingAction> { 108 class MediaKeySession::PendingAction : public GarbageCollectedFinalized<MediaKey Session::PendingAction> {
86 public: 109 public:
87 enum Type { 110 enum Type {
88 GenerateRequest, 111 GenerateRequest,
112 Load,
89 Update, 113 Update,
90 Close, 114 Close,
91 Remove 115 Remove
92 }; 116 };
93 117
94 Type type() const { return m_type; } 118 Type type() const { return m_type; }
95 119
96 const Persistent<ContentDecryptionModuleResult> result() const 120 const Persistent<ContentDecryptionModuleResult> result() const
97 { 121 {
98 return m_result; 122 return m_result;
99 } 123 }
100 124
101 const RefPtr<ArrayBuffer> data() const 125 const RefPtr<ArrayBuffer> data() const
102 { 126 {
103 ASSERT(m_type == GenerateRequest || m_type == Update); 127 ASSERT(m_type == GenerateRequest || m_type == Update);
104 return m_data; 128 return m_data;
105 } 129 }
106 130
107 const String& initDataType() const 131 const String& initDataType() const
108 { 132 {
109 ASSERT(m_type == GenerateRequest); 133 ASSERT(m_type == GenerateRequest);
110 return m_initDataType; 134 return m_stringData;
135 }
136
137 const String& sessionId() const
138 {
139 ASSERT(m_type == Load);
140 return m_stringData;
111 } 141 }
112 142
113 static PendingAction* CreatePendingGenerateRequest(ContentDecryptionModuleRe sult* result, const String& initDataType, PassRefPtr<ArrayBuffer> initData) 143 static PendingAction* CreatePendingGenerateRequest(ContentDecryptionModuleRe sult* result, const String& initDataType, PassRefPtr<ArrayBuffer> initData)
114 { 144 {
115 ASSERT(result); 145 ASSERT(result);
116 ASSERT(initData); 146 ASSERT(initData);
117 return new PendingAction(GenerateRequest, result, initDataType, initData ); 147 return new PendingAction(GenerateRequest, result, initDataType, initData );
118 } 148 }
119 149
150 static PendingAction* CreatePendingLoadRequest(ContentDecryptionModuleResult * result, const String& sessionId)
151 {
152 ASSERT(result);
153 return new PendingAction(Load, result, sessionId, PassRefPtr<ArrayBuffer >());
154 }
155
120 static PendingAction* CreatePendingUpdate(ContentDecryptionModuleResult* res ult, PassRefPtr<ArrayBuffer> data) 156 static PendingAction* CreatePendingUpdate(ContentDecryptionModuleResult* res ult, PassRefPtr<ArrayBuffer> data)
121 { 157 {
122 ASSERT(result); 158 ASSERT(result);
123 ASSERT(data); 159 ASSERT(data);
124 return new PendingAction(Update, result, String(), data); 160 return new PendingAction(Update, result, String(), data);
125 } 161 }
126 162
127 static PendingAction* CreatePendingClose(ContentDecryptionModuleResult* resu lt) 163 static PendingAction* CreatePendingClose(ContentDecryptionModuleResult* resu lt)
128 { 164 {
129 ASSERT(result); 165 ASSERT(result);
130 return new PendingAction(Close, result, String(), PassRefPtr<ArrayBuffer >()); 166 return new PendingAction(Close, result, String(), PassRefPtr<ArrayBuffer >());
131 } 167 }
132 168
133 static PendingAction* CreatePendingRemove(ContentDecryptionModuleResult* res ult) 169 static PendingAction* CreatePendingRemove(ContentDecryptionModuleResult* res ult)
134 { 170 {
135 ASSERT(result); 171 ASSERT(result);
136 return new PendingAction(Remove, result, String(), PassRefPtr<ArrayBuffe r>()); 172 return new PendingAction(Remove, result, String(), PassRefPtr<ArrayBuffe r>());
137 } 173 }
138 174
139 ~PendingAction() 175 ~PendingAction()
140 { 176 {
141 } 177 }
142 178
143 void trace(Visitor* visitor) 179 void trace(Visitor* visitor)
144 { 180 {
145 visitor->trace(m_result); 181 visitor->trace(m_result);
146 } 182 }
147 183
148 private: 184 private:
149 PendingAction(Type type, ContentDecryptionModuleResult* result, const String & initDataType, PassRefPtr<ArrayBuffer> data) 185 PendingAction(Type type, ContentDecryptionModuleResult* result, const String & stringData, PassRefPtr<ArrayBuffer> data)
150 : m_type(type) 186 : m_type(type)
151 , m_result(result) 187 , m_result(result)
152 , m_initDataType(initDataType) 188 , m_stringData(stringData)
153 , m_data(data) 189 , m_data(data)
154 { 190 {
155 } 191 }
156 192
157 const Type m_type; 193 const Type m_type;
158 const Member<ContentDecryptionModuleResult> m_result; 194 const Member<ContentDecryptionModuleResult> m_result;
159 const String m_initDataType; 195 const String m_stringData;
160 const RefPtr<ArrayBuffer> m_data; 196 const RefPtr<ArrayBuffer> m_data;
161 }; 197 };
162 198
163 // This class wraps the promise resolver used when initializing a new session 199 // This class wraps the promise resolver used when initializing a new session
164 // and is passed to Chromium to fullfill the promise. This implementation of 200 // and is passed to Chromium to fullfill the promise. This implementation of
165 // completeWithSession() will resolve the promise with void, while 201 // completeWithSession() will resolve the promise with void, while
166 // completeWithError() will reject the promise with an exception. complete() 202 // completeWithError() will reject the promise with an exception. complete()
167 // is not expected to be called, and will reject the promise. 203 // is not expected to be called, and will reject the promise.
168 class NewSessionResult : public ContentDecryptionModuleResult { 204 class NewSessionResult : public ContentDecryptionModuleResult {
169 public: 205 public:
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 void completeWithDOMException(ExceptionCode code, const String& errorMessage ) 253 void completeWithDOMException(ExceptionCode code, const String& errorMessage )
218 { 254 {
219 m_resolver->reject(DOMException::create(code, errorMessage)); 255 m_resolver->reject(DOMException::create(code, errorMessage));
220 m_resolver.clear(); 256 m_resolver.clear();
221 } 257 }
222 258
223 RefPtr<ScriptPromiseResolver> m_resolver; 259 RefPtr<ScriptPromiseResolver> m_resolver;
224 Member<MediaKeySession> m_session; 260 Member<MediaKeySession> m_session;
225 }; 261 };
226 262
263 // This class wraps the promise resolver used when loading a session
264 // and is passed to Chromium to fullfill the promise. This implementation of
265 // completeWithSession() will resolve the promise with true/false, while
266 // completeWithError() will reject the promise with an exception. complete()
267 // is not expected to be called, and will reject the promise.
268 class LoadSessionResult : public ContentDecryptionModuleResult {
269 public:
270 LoadSessionResult(ScriptState* scriptState, MediaKeySession* session)
271 : m_resolver(ScriptPromiseResolver::create(scriptState))
272 , m_session(session)
273 {
274 WTF_LOG(Media, "LoadSessionResult(%p)", this);
275 }
276
277 virtual ~LoadSessionResult()
278 {
279 WTF_LOG(Media, "~LoadSessionResult(%p)", this);
280 }
281
282 // ContentDecryptionModuleResult implementation.
283 virtual void complete() override
284 {
285 ASSERT_NOT_REACHED();
286 completeWithDOMException(InvalidStateError, "Unexpected completion.");
287 }
288
289 virtual void completeWithSession(WebContentDecryptionModuleResult::SessionSt atus status) override
290 {
291 bool result = false;
292 switch (status) {
293 case WebContentDecryptionModuleResult::NewSession:
294 result = true;
295 break;
296
297 case WebContentDecryptionModuleResult::SessionNotFound:
298 result = false;
299 break;
300
301 case WebContentDecryptionModuleResult::SessionAlreadyExists:
302 ASSERT_NOT_REACHED();
303 completeWithDOMException(InvalidStateError, "Unexpected completion." );
304 return;
305 }
306
307 m_session->finishLoad();
308 m_resolver->resolve(result);
309 m_resolver.clear();
310 }
311
312 virtual void completeWithError(WebContentDecryptionModuleException exception Code, unsigned long systemCode, const WebString& errorMessage) override
313 {
314 completeWithDOMException(WebCdmExceptionToExceptionCode(exceptionCode), errorMessage);
315 }
316
317 // It is only valid to call this before completion.
318 ScriptPromise promise() { return m_resolver->promise(); }
319
320 void trace(Visitor* visitor)
321 {
322 visitor->trace(m_session);
323 ContentDecryptionModuleResult::trace(visitor);
324 }
325
326 private:
327 // Reject the promise with a DOMException.
328 void completeWithDOMException(ExceptionCode code, const String& errorMessage )
329 {
330 m_resolver->reject(DOMException::create(code, errorMessage));
331 m_resolver.clear();
332 }
333
334 RefPtr<ScriptPromiseResolver> m_resolver;
335 Member<MediaKeySession> m_session;
336 };
337
227 MediaKeySession* MediaKeySession::create(ScriptState* scriptState, MediaKeys* me diaKeys, const String& sessionType) 338 MediaKeySession* MediaKeySession::create(ScriptState* scriptState, MediaKeys* me diaKeys, const String& sessionType)
228 { 339 {
229 ASSERT(sessionType == kTemporary || sessionType == kPersistent); 340 ASSERT(sessionType == kTemporary || sessionType == kPersistent);
230 RefPtrWillBeRawPtr<MediaKeySession> session = new MediaKeySession(scriptStat e, mediaKeys, sessionType); 341 RefPtrWillBeRawPtr<MediaKeySession> session = new MediaKeySession(scriptStat e, mediaKeys, sessionType);
231 session->suspendIfNeeded(); 342 session->suspendIfNeeded();
232 return session.get(); 343 return session.get();
233 } 344 }
234 345
346 bool MediaKeySession::isValidSessionType(const String& sessionType)
347 {
348 return (sessionType == kTemporary || sessionType == kPersistent);
349 }
350
235 MediaKeySession::MediaKeySession(ScriptState* scriptState, MediaKeys* mediaKeys, const String& sessionType) 351 MediaKeySession::MediaKeySession(ScriptState* scriptState, MediaKeys* mediaKeys, const String& sessionType)
236 : ActiveDOMObject(scriptState->executionContext()) 352 : ActiveDOMObject(scriptState->executionContext())
237 , m_keySystem(mediaKeys->keySystem()) 353 , m_keySystem(mediaKeys->keySystem())
238 , m_asyncEventQueue(GenericEventQueue::create(this)) 354 , m_asyncEventQueue(GenericEventQueue::create(this))
239 , m_mediaKeys(mediaKeys) 355 , m_mediaKeys(mediaKeys)
240 , m_sessionType(sessionType) 356 , m_sessionType(sessionType)
241 , m_expiration(std::numeric_limits<double>::quiet_NaN()) 357 , m_expiration(std::numeric_limits<double>::quiet_NaN())
242 , m_isUninitialized(true) 358 , m_isUninitialized(true)
243 , m_isCallable(false) 359 , m_isCallable(false)
244 , m_isClosed(false) 360 , m_isClosed(false)
(...skipping 13 matching lines...) Expand all
258 // 2.1 Let the sessionId attribute be the empty string. 374 // 2.1 Let the sessionId attribute be the empty string.
259 ASSERT(sessionId().isEmpty()); 375 ASSERT(sessionId().isEmpty());
260 376
261 // 2.2 Let the expiration attribute be NaN. 377 // 2.2 Let the expiration attribute be NaN.
262 ASSERT(std::isnan(m_expiration)); 378 ASSERT(std::isnan(m_expiration));
263 379
264 // 2.3 Let the closed attribute be a new promise. 380 // 2.3 Let the closed attribute be a new promise.
265 ASSERT(!closed(scriptState).isUndefinedOrNull()); 381 ASSERT(!closed(scriptState).isUndefinedOrNull());
266 382
267 // 2.4 Let the session type be sessionType. 383 // 2.4 Let the session type be sessionType.
268 ASSERT(sessionType == m_sessionType); 384 ASSERT(isValidSessionType(sessionType));
269 385
270 // 2.5 Let uninitialized be true. 386 // 2.5 Let uninitialized be true.
271 ASSERT(m_isUninitialized); 387 ASSERT(m_isUninitialized);
272 388
273 // 2.6 Let callable be false. 389 // 2.6 Let callable be false.
274 ASSERT(!m_isCallable); 390 ASSERT(!m_isCallable);
275 } 391 }
276 392
277 MediaKeySession::~MediaKeySession() 393 MediaKeySession::~MediaKeySession()
278 { 394 {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 // 10. Run the following steps asynchronously (documented in 486 // 10. Run the following steps asynchronously (documented in
371 // actionTimerFired()) 487 // actionTimerFired())
372 m_pendingActions.append(PendingAction::CreatePendingGenerateRequest(result, initDataType, initData)); 488 m_pendingActions.append(PendingAction::CreatePendingGenerateRequest(result, initDataType, initData));
373 ASSERT(!m_actionTimer.isActive()); 489 ASSERT(!m_actionTimer.isActive());
374 m_actionTimer.startOneShot(0, FROM_HERE); 490 m_actionTimer.startOneShot(0, FROM_HERE);
375 491
376 // 11. Return promise. 492 // 11. Return promise.
377 return promise; 493 return promise;
378 } 494 }
379 495
496 ScriptPromise MediaKeySession::load(ScriptState* scriptState, const String& sess ionId)
497 {
498 WTF_LOG(Media, "MediaKeySession(%p)::load %s", this, sessionId.ascii().data( ));
499
500 // From https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/e ncrypted-media.html#dom-load:
501 // The load(sessionId) method loads the data stored for the sessionId into
502 // the session represented by the object. It must run the following steps:
503
504 // 1. If this object's uninitialized value is false, return a promise
505 // rejected with a new DOMException whose name is "InvalidStateError".
506 if (!m_isUninitialized) {
507 return ScriptPromise::rejectWithDOMException(
508 scriptState, DOMException::create(InvalidStateError, "The session is already initialized."));
509 }
510
511 // 2. Let this object's uninitialized be false.
512 m_isUninitialized = false;
513
514 // 3. If sessionId is an empty string, return a promise rejected with a
515 // new DOMException whose name is "InvalidAccessError".
516 if (sessionId.isEmpty()) {
517 return ScriptPromise::rejectWithDOMException(
518 scriptState, DOMException::create(InvalidAccessError, "The sessionId parameter is empty."));
519 }
520
521 // 4. If this object's session type is not "persistent", return a promise
522 // rejected with a new DOMException whose name is "InvalidAccessError".
523 if (m_sessionType != kPersistent) {
524 return ScriptPromise::rejectWithDOMException(
525 scriptState, DOMException::create(InvalidAccessError, "The session t ype is not 'persistent'."));
526 }
527
528 // 5. Let media keys be the MediaKeys object that created this object.
529 // (Done in constructor.)
530 ASSERT(m_mediaKeys);
531
532 // 6. If the content decryption module corresponding to media keys's
533 // keySystem attribute does not support loading previous sessions,
534 // return a promise rejected with a new DOMException whose name is
535 // "NotSupportedError".
536 // (Done by CDM.)
537
538 // 7. Let promise be a new promise.
539 LoadSessionResult* result = new LoadSessionResult(scriptState, this);
540 ScriptPromise promise = result->promise();
541
542 // 8. Run the following steps asynchronously (documented in
543 // actionTimerFired())
544 m_pendingActions.append(PendingAction::CreatePendingLoadRequest(result, sess ionId));
545 ASSERT(!m_actionTimer.isActive());
546 m_actionTimer.startOneShot(0, FROM_HERE);
547
548 // 9. Return promise.
549 return promise;
550 }
551
380 ScriptPromise MediaKeySession::update(ScriptState* scriptState, ArrayBuffer* res ponse) 552 ScriptPromise MediaKeySession::update(ScriptState* scriptState, ArrayBuffer* res ponse)
381 { 553 {
382 RefPtr<ArrayBuffer> responseCopy = ArrayBuffer::create(response->data(), res ponse->byteLength()); 554 RefPtr<ArrayBuffer> responseCopy = ArrayBuffer::create(response->data(), res ponse->byteLength());
383 return updateInternal(scriptState, responseCopy.release()); 555 return updateInternal(scriptState, responseCopy.release());
384 } 556 }
385 557
386 ScriptPromise MediaKeySession::update(ScriptState* scriptState, ArrayBufferView* response) 558 ScriptPromise MediaKeySession::update(ScriptState* scriptState, ArrayBufferView* response)
387 { 559 {
388 RefPtr<ArrayBuffer> responseCopy = ArrayBuffer::create(response->baseAddress (), response->byteLength()); 560 RefPtr<ArrayBuffer> responseCopy = ArrayBuffer::create(response->baseAddress (), response->byteLength());
389 return updateInternal(scriptState, responseCopy.release()); 561 return updateInternal(scriptState, responseCopy.release());
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 // "NotSupportedError". 705 // "NotSupportedError".
534 // 10.3.3 Let request be a request (e.g. a license request) 706 // 10.3.3 Let request be a request (e.g. a license request)
535 // generated based on the init data, which is interpreted 707 // generated based on the init data, which is interpreted
536 // per initDataType, and session type. 708 // per initDataType, and session type.
537 m_session->initializeNewSession(action->initDataType(), static_cast< unsigned char*>(action->data()->data()), action->data()->byteLength(), m_session Type, action->result()->result()); 709 m_session->initializeNewSession(action->initDataType(), static_cast< unsigned char*>(action->data()->data()), action->data()->byteLength(), m_session Type, action->result()->result());
538 710
539 // Remainder of steps executed in finishGenerateRequest(), called 711 // Remainder of steps executed in finishGenerateRequest(), called
540 // when |result| is resolved. 712 // when |result| is resolved.
541 break; 713 break;
542 714
715 case PendingAction::Load:
716 // NOTE: Continue step 8 of MediaKeySession::load().
717
718 // 8.1 Let sanitized session ID be a validated and/or sanitized
719 // version of sessionId. The user agent should thoroughly
720 // validate the sessionId value before passing it to the CDM.
721 // At a minimum, this should include checking that the length
722 // and value (e.g. alphanumeric) are reasonable.
723 // 8.2 If the previous step failed, reject promise with a new
724 // DOMException whose name is "InvalidAccessError".
725 if (!isValidSessionId(action->sessionId())) {
726 action->result()->completeWithError(WebContentDecryptionModuleEx ceptionInvalidAccessError, 0, "Invalid sessionId");
727 return;
728 }
729
730 // 8.3 Let expiration time be NaN.
731 // (Done in the constructor.)
732 ASSERT(std::isnan(m_expiration));
733
734 // 8.4 Let message be null.
735 // 8.5 Let message type be null.
736 // (Will be provided by the CDM if needed.)
737
738 // 8.6 Let origin be the origin of this object's Document.
739 // (Obtained previously when CDM created.)
740
741 // 8.7 Let cdm be the CDM loaded during the initialization of media
742 // keys.
743 // 8.8 Use the cdm to execute the following steps:
744 // 8.8.1 If there is no data stored for the sanitized session ID in
745 // the origin, resolve promise with false.
746 // 8.8.2 Let session data be the data stored for the sanitized
747 // session ID in the origin. This must not include data from
748 // other origin(s) or that is not associated with an origin.
749 // 8.8.3 If there is an unclosed "persistent" session in any
750 // Document representing the session data, reject promise
751 // with a new DOMException whose name is "QuotaExceededError".
752 // 8.8.4 In other words, do not create a session if a non-closed
753 // persistent session already exists for this sanitized
754 // session ID in any browsing context.
755 // 8.8.5 Load the session data.
756 // 8.8.6 If the session data indicates an expiration time for the
757 // session, let expiration time be the expiration time
758 // in milliseconds since 01 January 1970 UTC.
759 // 8.8.6 If the CDM needs to send a message:
760 // 8.8.6.1 Let message be a message generated by the CDM based on
761 // the session data.
762 // 8.8.6.2 Let message type be the appropriate MediaKeyMessageType
763 // for the message.
764 // 8.9 If any of the preceding steps failed, reject promise with a
765 // new DOMException whose name is the appropriate error name.
766 m_session->load(action->sessionId(), action->result()->result());
767
768 // Remainder of steps executed in finishLoad(), called
769 // when |result| is resolved.
770 break;
771
543 case PendingAction::Update: 772 case PendingAction::Update:
544 WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Update", this ); 773 WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Update", this );
545 // NOTE: Continued from step 4 of MediaKeySession::update(). 774 // NOTE: Continued from step 4 of MediaKeySession::update().
546 // Continue the update call by passing message to the cdm. Once 775 // Continue the update call by passing message to the cdm. Once
547 // completed, it will resolve/reject the promise. 776 // completed, it will resolve/reject the promise.
548 m_session->update(static_cast<unsigned char*>(action->data()->data() ), action->data()->byteLength(), action->result()->result()); 777 m_session->update(static_cast<unsigned char*>(action->data()->data() ), action->data()->byteLength(), action->result()->result());
549 break; 778 break;
550 779
551 case PendingAction::Close: 780 case PendingAction::Close:
552 WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Close", this) ; 781 WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Close", this) ;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=26758 835 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=26758
607 836
608 // 10.7 Run the Queue a "message" Event algorithm on the session, 837 // 10.7 Run the Queue a "message" Event algorithm on the session,
609 // providing request and null. 838 // providing request and null.
610 // (Done by the CDM). 839 // (Done by the CDM).
611 840
612 // 10.8 Let this object's callable be true. 841 // 10.8 Let this object's callable be true.
613 m_isCallable = true; 842 m_isCallable = true;
614 } 843 }
615 844
845 void MediaKeySession::finishLoad()
846 {
847 // 8.10 Set the sessionId attribute to sanitized session ID.
848 ASSERT(!sessionId().isEmpty());
849
850 // 8.11 Let this object's callable be true.
851 m_isCallable = true;
852
853 // 8.12 If the loaded session contains usable keys, run the Usable
854 // Keys Changed algorithm on the session. The algorithm may
855 // also be run later should additional processing be necessary
856 // to determine with certainty whether one or more keys is
857 // usable.
858 // (Done by the CDM.)
859
860 // 8.13 Run the Update Expiration algorithm on the session,
861 // providing expiration time.
862 // (Done by the CDM.)
863
864 // 8.14 If message is not null, run the Queue a "message" Event
865 // algorithm on the session, providing message type and
866 // message.
867 // (Done by the CDM.)
868 }
869
616 // Queue a task to fire a simple event named keymessage at the new object. 870 // Queue a task to fire a simple event named keymessage at the new object.
617 void MediaKeySession::message(const unsigned char* message, size_t messageLength , const WebURL& destinationURL) 871 void MediaKeySession::message(const unsigned char* message, size_t messageLength , const WebURL& destinationURL)
618 { 872 {
619 WTF_LOG(Media, "MediaKeySession(%p)::message", this); 873 WTF_LOG(Media, "MediaKeySession(%p)::message", this);
620 874
621 // Verify that 'message' not fired before session initialization is complete . 875 // Verify that 'message' not fired before session initialization is complete .
622 ASSERT(m_isCallable); 876 ASSERT(m_isCallable);
623 877
624 MediaKeyMessageEventInit init; 878 MediaKeyMessageEventInit init;
625 init.bubbles = false; 879 init.bubbles = false;
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 { 1002 {
749 visitor->trace(m_error); 1003 visitor->trace(m_error);
750 visitor->trace(m_asyncEventQueue); 1004 visitor->trace(m_asyncEventQueue);
751 visitor->trace(m_pendingActions); 1005 visitor->trace(m_pendingActions);
752 visitor->trace(m_mediaKeys); 1006 visitor->trace(m_mediaKeys);
753 visitor->trace(m_closedPromise); 1007 visitor->trace(m_closedPromise);
754 EventTargetWithInlineData::trace(visitor); 1008 EventTargetWithInlineData::trace(visitor);
755 } 1009 }
756 1010
757 } // namespace blink 1011 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/encryptedmedia/MediaKeySession.h ('k') | Source/modules/encryptedmedia/MediaKeySession.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698