OLD | NEW |
---|---|
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 Loading... | |
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 | 53 |
54 namespace { | |
55 | |
56 const char* kPersistent = "persistent"; | |
ddorwin
2014/10/08 21:48:26
Do we have this in two locations now?
Should we ju
jrummell
2014/10/08 22:57:00
The string is currently passed to Chromium (so we
ddorwin
2014/10/08 23:08:48
Okay. Even more reason to change to enums! :)
| |
57 | |
58 // Minimum and maximum length for session ids. | |
59 enum { | |
60 MinSessionIdLength = 1, | |
61 MaxSessionIdLength = 512 | |
62 }; | |
63 | |
64 } // namespace | |
65 | |
53 namespace blink { | 66 namespace blink { |
54 | 67 |
55 static bool isKeySystemSupportedWithInitDataType(const String& keySystem, const String& initDataType) | 68 static bool isKeySystemSupportedWithInitDataType(const String& keySystem, const String& initDataType) |
56 { | 69 { |
57 ASSERT(!keySystem.isEmpty()); | 70 ASSERT(!keySystem.isEmpty()); |
58 | 71 |
59 // FIXME: initDataType != contentType. Implement this properly. | 72 // FIXME: initDataType != contentType. Implement this properly. |
60 // http://crbug.com/385874. | 73 // http://crbug.com/385874. |
61 String contentType = initDataType; | 74 String contentType = initDataType; |
62 if (initDataType == "webm") { | 75 if (initDataType == "webm") { |
63 contentType = "video/webm"; | 76 contentType = "video/webm"; |
64 } else if (initDataType == "cenc") { | 77 } else if (initDataType == "cenc") { |
65 contentType = "video/mp4"; | 78 contentType = "video/mp4"; |
66 } | 79 } |
67 | 80 |
68 ContentType type(contentType); | 81 ContentType type(contentType); |
69 return MIMETypeRegistry::isSupportedEncryptedMediaMIMEType(keySystem, type.t ype(), type.parameter("codecs")); | 82 return MIMETypeRegistry::isSupportedEncryptedMediaMIMEType(keySystem, type.t ype(), type.parameter("codecs")); |
70 } | 83 } |
71 | 84 |
85 // Checks that |sessionId| looks correct. Returns true if all tests pass, | |
ddorwin
2014/10/08 21:48:26
Returns whether...
jrummell
2014/10/08 22:57:00
Done.
| |
86 // false otherwise. | |
87 static bool isValidSessionId(const String& sessionId) | |
88 { | |
89 if ((sessionId.length() < MinSessionIdLength) || (sessionId.length() > MaxSe ssionIdLength)) | |
90 return false; | |
91 | |
92 if (!sessionId.containsOnlyASCII()) | |
93 return false; | |
94 | |
95 // Check that the sessionId only contains alphanumeric characters. | |
96 for (unsigned i = 0; i < sessionId.length(); ++i) { | |
97 if (!isASCIIAlphanumeric(sessionId[i])) | |
98 return false; | |
99 } | |
100 | |
101 return true; | |
102 } | |
103 | |
72 // A class holding a pending action. | 104 // A class holding a pending action. |
73 class MediaKeySession::PendingAction : public GarbageCollectedFinalized<MediaKey Session::PendingAction> { | 105 class MediaKeySession::PendingAction : public GarbageCollectedFinalized<MediaKey Session::PendingAction> { |
74 public: | 106 public: |
75 enum Type { | 107 enum Type { |
76 GenerateRequest, | 108 GenerateRequest, |
109 Load, | |
77 Update, | 110 Update, |
78 Release | 111 Release |
79 }; | 112 }; |
80 | 113 |
81 Type type() const { return m_type; } | 114 Type type() const { return m_type; } |
82 | 115 |
83 const Persistent<ContentDecryptionModuleResult> result() const | 116 const Persistent<ContentDecryptionModuleResult> result() const |
84 { | 117 { |
85 return m_result; | 118 return m_result; |
86 } | 119 } |
87 | 120 |
88 const RefPtr<ArrayBuffer> data() const | 121 const RefPtr<ArrayBuffer> data() const |
89 { | 122 { |
90 ASSERT(m_type == GenerateRequest || m_type == Update); | 123 ASSERT(m_type == GenerateRequest || m_type == Update); |
91 return m_data; | 124 return m_data; |
92 } | 125 } |
93 | 126 |
94 const String& initDataType() const | 127 const String& initDataType() const |
95 { | 128 { |
96 ASSERT(m_type == GenerateRequest); | 129 ASSERT(m_type == GenerateRequest); |
97 return m_initDataType; | 130 return m_initDataType; |
98 } | 131 } |
99 | 132 |
133 const String& sessionId() const | |
134 { | |
135 ASSERT(m_type == Load); | |
136 return m_initDataType; | |
ddorwin
2014/10/08 21:48:26
C&P error
jrummell
2014/10/08 22:57:01
Not really. m_initDataType used for both values. R
| |
137 } | |
138 | |
100 static PendingAction* CreatePendingGenerateRequest(ContentDecryptionModuleRe sult* result, const String& initDataType, PassRefPtr<ArrayBuffer> initData) | 139 static PendingAction* CreatePendingGenerateRequest(ContentDecryptionModuleRe sult* result, const String& initDataType, PassRefPtr<ArrayBuffer> initData) |
101 { | 140 { |
102 ASSERT(result); | 141 ASSERT(result); |
103 ASSERT(initData); | 142 ASSERT(initData); |
104 return new PendingAction(GenerateRequest, result, initDataType, initData ); | 143 return new PendingAction(GenerateRequest, result, initDataType, initData ); |
105 } | 144 } |
106 | 145 |
146 static PendingAction* CreatePendingLoadRequest(ContentDecryptionModuleResult * result, const String& sessionId) | |
147 { | |
148 ASSERT(result); | |
149 return new PendingAction(Load, result, sessionId, PassRefPtr<ArrayBuffer >()); | |
150 } | |
151 | |
107 static PendingAction* CreatePendingUpdate(ContentDecryptionModuleResult* res ult, PassRefPtr<ArrayBuffer> data) | 152 static PendingAction* CreatePendingUpdate(ContentDecryptionModuleResult* res ult, PassRefPtr<ArrayBuffer> data) |
108 { | 153 { |
109 ASSERT(result); | 154 ASSERT(result); |
110 ASSERT(data); | 155 ASSERT(data); |
111 return new PendingAction(Update, result, String(), data); | 156 return new PendingAction(Update, result, String(), data); |
112 } | 157 } |
113 | 158 |
114 static PendingAction* CreatePendingRelease(ContentDecryptionModuleResult* re sult) | 159 static PendingAction* CreatePendingRelease(ContentDecryptionModuleResult* re sult) |
115 { | 160 { |
116 ASSERT(result); | 161 ASSERT(result); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
198 void completeWithDOMException(ExceptionCode code, const String& errorMessage ) | 243 void completeWithDOMException(ExceptionCode code, const String& errorMessage ) |
199 { | 244 { |
200 m_resolver->reject(DOMException::create(code, errorMessage)); | 245 m_resolver->reject(DOMException::create(code, errorMessage)); |
201 m_resolver.clear(); | 246 m_resolver.clear(); |
202 } | 247 } |
203 | 248 |
204 RefPtr<ScriptPromiseResolver> m_resolver; | 249 RefPtr<ScriptPromiseResolver> m_resolver; |
205 Member<MediaKeySession> m_session; | 250 Member<MediaKeySession> m_session; |
206 }; | 251 }; |
207 | 252 |
253 // This class wraps the promise resolver used when loading a session | |
254 // and is passed to Chromium to fullfill the promise. This implementation of | |
255 // completeWithSession() will resolve the promise with true/false, while | |
256 // completeWithError() will reject the promise with an exception. complete() | |
257 // is not expected to be called, and will reject the promise. | |
258 class LoadSessionResult : public ContentDecryptionModuleResult { | |
259 public: | |
260 LoadSessionResult(ScriptState* scriptState, MediaKeySession* session) | |
261 : m_resolver(ScriptPromiseResolver::create(scriptState)) | |
262 , m_session(session) | |
263 { | |
264 WTF_LOG(Media, "LoadSessionResult(%p)", this); | |
265 } | |
266 | |
267 virtual ~LoadSessionResult() | |
268 { | |
269 WTF_LOG(Media, "~LoadSessionResult(%p)", this); | |
270 } | |
271 | |
272 // ContentDecryptionModuleResult implementation. | |
273 virtual void complete() OVERRIDE | |
274 { | |
275 ASSERT_NOT_REACHED(); | |
276 completeWithDOMException(InvalidStateError, "Unexpected completion."); | |
277 } | |
278 | |
279 virtual void completeWithSession(WebContentDecryptionModuleResult::SessionSt atus status) OVERRIDE | |
280 { | |
281 bool result; | |
ddorwin
2014/10/08 21:48:26
Uninitialized, though I guess that was allowed (an
jrummell
2014/10/08 22:57:01
Acknowledged.
| |
282 switch (status) { | |
283 case WebContentDecryptionModuleResult::NewSession: | |
284 result = true; | |
285 break; | |
286 | |
287 case WebContentDecryptionModuleResult::SessionNotFound: | |
288 result = false; | |
289 break; | |
290 | |
291 case WebContentDecryptionModuleResult::SessionAlreadyExists: | |
292 ASSERT_NOT_REACHED(); | |
293 completeWithDOMException(InvalidStateError, "Unexpected completion." ); | |
294 return; | |
295 } | |
296 | |
297 m_session->finishLoad(); | |
298 m_resolver->resolve(result); | |
299 m_resolver.clear(); | |
300 } | |
301 | |
302 virtual void completeWithError(WebContentDecryptionModuleException exception Code, unsigned long systemCode, const WebString& errorMessage) OVERRIDE | |
303 { | |
304 completeWithDOMException(WebCdmExceptionToExceptionCode(exceptionCode), errorMessage); | |
305 } | |
306 | |
307 // It is only valid to call this before completion. | |
308 ScriptPromise promise() { return m_resolver->promise(); } | |
309 | |
310 void trace(Visitor* visitor) | |
311 { | |
312 visitor->trace(m_session); | |
313 ContentDecryptionModuleResult::trace(visitor); | |
314 } | |
315 | |
316 private: | |
317 // Reject the promise with a DOMException. | |
318 void completeWithDOMException(ExceptionCode code, const String& errorMessage ) | |
319 { | |
320 m_resolver->reject(DOMException::create(code, errorMessage)); | |
321 m_resolver.clear(); | |
322 } | |
323 | |
324 RefPtr<ScriptPromiseResolver> m_resolver; | |
325 Member<MediaKeySession> m_session; | |
326 }; | |
327 | |
208 MediaKeySession* MediaKeySession::create(ScriptState* scriptState, MediaKeys* me diaKeys, const String& sessionType) | 328 MediaKeySession* MediaKeySession::create(ScriptState* scriptState, MediaKeys* me diaKeys, const String& sessionType) |
209 { | 329 { |
210 RefPtrWillBeRawPtr<MediaKeySession> session = adoptRefCountedGarbageCollecte dWillBeNoop(new MediaKeySession(scriptState, mediaKeys, sessionType)); | 330 RefPtrWillBeRawPtr<MediaKeySession> session = adoptRefCountedGarbageCollecte dWillBeNoop(new MediaKeySession(scriptState, mediaKeys, sessionType)); |
211 session->suspendIfNeeded(); | 331 session->suspendIfNeeded(); |
212 return session.get(); | 332 return session.get(); |
213 } | 333 } |
214 | 334 |
215 MediaKeySession::MediaKeySession(ScriptState* scriptState, MediaKeys* mediaKeys, const String& sessionType) | 335 MediaKeySession::MediaKeySession(ScriptState* scriptState, MediaKeys* mediaKeys, const String& sessionType) |
216 : ActiveDOMObject(scriptState->executionContext()) | 336 : ActiveDOMObject(scriptState->executionContext()) |
217 , m_keySystem(mediaKeys->keySystem()) | 337 , m_keySystem(mediaKeys->keySystem()) |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
349 // 10. Run the following steps asynchronously (documented in | 469 // 10. Run the following steps asynchronously (documented in |
350 // actionTimerFired()) | 470 // actionTimerFired()) |
351 m_pendingActions.append(PendingAction::CreatePendingGenerateRequest(result, initDataType, initData)); | 471 m_pendingActions.append(PendingAction::CreatePendingGenerateRequest(result, initDataType, initData)); |
352 ASSERT(!m_actionTimer.isActive()); | 472 ASSERT(!m_actionTimer.isActive()); |
353 m_actionTimer.startOneShot(0, FROM_HERE); | 473 m_actionTimer.startOneShot(0, FROM_HERE); |
354 | 474 |
355 // 11. Return promise. | 475 // 11. Return promise. |
356 return promise; | 476 return promise; |
357 } | 477 } |
358 | 478 |
479 ScriptPromise MediaKeySession::load(ScriptState* scriptState, const String& sess ionId) | |
480 { | |
481 WTF_LOG(Media, "MediaKeySession(%p)::load %s", this, sessionId.ascii().data( )); | |
482 | |
483 // From https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/e ncrypted-media.html#dom-load: | |
484 // The load(sessionId) method loads the data stored for the sessionId into | |
485 // the session represented by the object. It must run the following steps: | |
486 | |
487 // 1. If this object's uninitialized value is false, return a promise | |
488 // rejected with a new DOMException whose name is "InvalidStateError". | |
489 if (!m_isUninitialized) { | |
490 return ScriptPromise::rejectWithDOMException( | |
491 scriptState, DOMException::create(InvalidStateError, "The session is already initialized.")); | |
492 } | |
493 | |
494 // 2. Let this object's uninitialized be false. | |
495 m_isUninitialized = false; | |
496 | |
497 // 3. If sessionId is an empty string, return a promise rejected with a | |
498 // new DOMException whose name is "InvalidAccessError". | |
499 if (sessionId.isEmpty()) { | |
500 return ScriptPromise::rejectWithDOMException( | |
501 scriptState, DOMException::create(InvalidAccessError, "The sessionId parameter is empty.")); | |
502 } | |
503 | |
504 // 4. If this object's session type is not "persistent", return a promise | |
505 // rejected with a new DOMException whose name is "InvalidAccessError". | |
506 if (m_sessionType != kPersistent) { | |
507 return ScriptPromise::rejectWithDOMException( | |
508 scriptState, DOMException::create(InvalidAccessError, "The session t ype is not \"persistent\".")); | |
ddorwin
2014/10/08 21:48:27
You could just use single quotes too.
jrummell
2014/10/08 22:57:00
Done.
| |
509 } | |
510 | |
511 // 5. Let media keys be the MediaKeys object that created this object. | |
512 // (Done in constructor.) | |
513 ASSERT(m_mediaKeys); | |
514 | |
515 // 6. If the content decryption module corresponding to media keys's | |
516 // keySystem attribute does not support loading previous sessions, | |
517 // return a promise rejected with a new DOMException whose name is | |
518 // "NotSupportedError". | |
519 // (Done by CDM.) | |
520 | |
521 // 7. Let promise be a new promise. | |
522 LoadSessionResult* result = new LoadSessionResult(scriptState, this); | |
523 ScriptPromise promise = result->promise(); | |
524 | |
525 // 8. Run the following steps asynchronously (documented in | |
526 // actionTimerFired()) | |
527 m_pendingActions.append(PendingAction::CreatePendingLoadRequest(result, sess ionId)); | |
528 ASSERT(!m_actionTimer.isActive()); | |
529 m_actionTimer.startOneShot(0, FROM_HERE); | |
530 | |
531 // 9. Return promise. | |
532 return promise; | |
533 } | |
534 | |
359 ScriptPromise MediaKeySession::update(ScriptState* scriptState, ArrayBuffer* res ponse) | 535 ScriptPromise MediaKeySession::update(ScriptState* scriptState, ArrayBuffer* res ponse) |
360 { | 536 { |
361 RefPtr<ArrayBuffer> responseCopy = ArrayBuffer::create(response->data(), res ponse->byteLength()); | 537 RefPtr<ArrayBuffer> responseCopy = ArrayBuffer::create(response->data(), res ponse->byteLength()); |
362 return updateInternal(scriptState, responseCopy.release()); | 538 return updateInternal(scriptState, responseCopy.release()); |
363 } | 539 } |
364 | 540 |
365 ScriptPromise MediaKeySession::update(ScriptState* scriptState, ArrayBufferView* response) | 541 ScriptPromise MediaKeySession::update(ScriptState* scriptState, ArrayBufferView* response) |
366 { | 542 { |
367 RefPtr<ArrayBuffer> responseCopy = ArrayBuffer::create(response->baseAddress (), response->byteLength()); | 543 RefPtr<ArrayBuffer> responseCopy = ArrayBuffer::create(response->baseAddress (), response->byteLength()); |
368 return updateInternal(scriptState, responseCopy.release()); | 544 return updateInternal(scriptState, responseCopy.release()); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 // "NotSupportedError". | 640 // "NotSupportedError". |
465 // 10.3.3 Let request be a request (e.g. a license request) | 641 // 10.3.3 Let request be a request (e.g. a license request) |
466 // generated based on the init data, which is interpreted | 642 // generated based on the init data, which is interpreted |
467 // per initDataType, and session type. | 643 // per initDataType, and session type. |
468 m_session->initializeNewSession(action->initDataType(), static_cast< unsigned char*>(action->data()->data()), action->data()->byteLength(), m_session Type, action->result()->result()); | 644 m_session->initializeNewSession(action->initDataType(), static_cast< unsigned char*>(action->data()->data()), action->data()->byteLength(), m_session Type, action->result()->result()); |
469 | 645 |
470 // Remainder of steps executed in finishGenerateRequest(), called | 646 // Remainder of steps executed in finishGenerateRequest(), called |
471 // when |result| is resolved. | 647 // when |result| is resolved. |
472 break; | 648 break; |
473 | 649 |
650 case PendingAction::Load: | |
651 // NOTE: Continue step 8 of MediaKeySession::load(). | |
652 | |
653 // 8.1 Let sanitized session ID be a validated and/or sanitized | |
654 // version of sessionId. The user agent should thoroughly | |
655 // validate the sessionId value before passing it to the CDM. | |
656 // At a minimum, this should include checking that the length | |
657 // and value (e.g. alphanumeric) are reasonable. | |
658 // 8.2 If the previous step failed, reject promise with a new | |
659 // DOMException whose name is "InvalidAccessError". | |
660 if (!isValidSessionId(action->sessionId())) { | |
661 action->result()->completeWithError(WebContentDecryptionModuleEx ceptionInvalidAccessError, 0, "Invalid sessionId"); | |
662 return; | |
663 } | |
664 | |
665 // 8.3 Let expiration time be NaN. | |
666 // FIXME: Implement expiration attribute. | |
667 | |
668 // 8.4 Let message be null. | |
669 // 8.5 Let message type be null. | |
670 // (Will be provided by the CDM if needed.) | |
671 | |
672 // 8.6 Let origin be the origin of this object's Document. | |
673 // (Obtained previously when CDM created.) | |
674 | |
675 // 8.7 Let cdm be the CDM loaded during the initialization of media | |
676 // keys. | |
677 // 8.8 Use the cdm to execute the following steps: | |
678 // 8.8.1 If there is no data stored for the sanitized session ID in | |
679 // the origin, resolve promise with false. | |
680 // 8.8.2 Let session data be the data stored for the sanitized | |
681 // session ID in the origin. This must not include data from | |
682 // other origin(s) or that is not associated with an origin. | |
683 // 8.8.3 If there is an unclosed "persistent" session in any | |
684 // Document representing the session data, reject promise | |
685 // with a new DOMException whose name is "QuotaExceededError". | |
686 // 8.8.4 In other words, do not create a session if a non-closed | |
687 // persistent session already exists for this sanitized | |
688 // session ID in any browsing context. | |
689 // 8.8.5 Load the session data. | |
690 // 8.8.6 If the session data indicates an expiration time for the | |
691 // session, let expiration time be the expiration time | |
692 // in milliseconds since 01 January 1970 UTC. | |
693 // 8.8.6 If the CDM needs to send a message: | |
694 // 8.8.6.1 Let message be a message generated by the CDM based on | |
695 // the session data. | |
696 // 8.8.6.2 Let message type be the appropriate MediaKeyMessageType | |
697 // for the message. | |
698 // 8.9 If any of the preceding steps failed, reject promise with a | |
699 // new DOMException whose name is the appropriate error name. | |
700 m_session->load(action->sessionId(), action->result()->result()); | |
701 | |
702 // Remainder of steps executed in finishLoad(), called | |
703 // when |result| is resolved. | |
704 break; | |
705 | |
474 case PendingAction::Update: | 706 case PendingAction::Update: |
475 WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Update", this ); | 707 WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Update", this ); |
476 // NOTE: Continued from step 4 of MediaKeySession::update(). | 708 // NOTE: Continued from step 4 of MediaKeySession::update(). |
477 // Continue the update call by passing message to the cdm. Once | 709 // Continue the update call by passing message to the cdm. Once |
478 // completed, it will resolve/reject the promise. | 710 // completed, it will resolve/reject the promise. |
479 m_session->update(static_cast<unsigned char*>(action->data()->data() ), action->data()->byteLength(), action->result()->result()); | 711 m_session->update(static_cast<unsigned char*>(action->data()->data() ), action->data()->byteLength(), action->result()->result()); |
480 break; | 712 break; |
481 | 713 |
482 case PendingAction::Release: | 714 case PendingAction::Release: |
483 WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Release", thi s); | 715 WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Release", thi s); |
(...skipping 26 matching lines...) Expand all Loading... | |
510 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=26758 | 742 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=26758 |
511 | 743 |
512 // 10.7 Run the Queue a "message" Event algorithm on the session, | 744 // 10.7 Run the Queue a "message" Event algorithm on the session, |
513 // providing request and null. | 745 // providing request and null. |
514 // (Done by the CDM). | 746 // (Done by the CDM). |
515 | 747 |
516 // 10.8 Let this object's callable be true. | 748 // 10.8 Let this object's callable be true. |
517 m_isCallable = true; | 749 m_isCallable = true; |
518 } | 750 } |
519 | 751 |
752 void MediaKeySession::finishLoad() | |
753 { | |
754 // 8.10 Set the sessionId attribute to sanitized session ID. | |
755 ASSERT(!sessionId().isEmpty()); | |
756 | |
757 // 8.11 Let this object's callable be true. | |
758 m_isCallable = true; | |
759 | |
760 // 8.12 If the loaded session contains usable keys, run the Usable | |
761 // Keys Changed algorithm on the session. The algorithm may | |
762 // also be run later should additional processing be necessary | |
763 // to determine with certainty whether one or more keys is | |
764 // usable. | |
765 // (Done by the CDM.) | |
ddorwin
2014/10/08 21:48:26
Does our code ensure that the CDM does not do thes
jrummell
2014/10/08 22:57:01
Yes (assuming resolving this promise and generatin
| |
766 | |
767 // 8.13 Run the Update Expiration algorithm on the session, | |
768 // providing expiration time. | |
769 // (Done by the CDM.) | |
770 | |
771 // 8.14 If message is not null, run the Queue a "message" Event | |
772 // algorithm on the session, providing message type and | |
773 // message. | |
774 // (Done by the CDM.) | |
775 } | |
776 | |
520 // Queue a task to fire a simple event named keymessage at the new object. | 777 // Queue a task to fire a simple event named keymessage at the new object. |
521 void MediaKeySession::message(const unsigned char* message, size_t messageLength , const WebURL& destinationURL) | 778 void MediaKeySession::message(const unsigned char* message, size_t messageLength , const WebURL& destinationURL) |
522 { | 779 { |
523 WTF_LOG(Media, "MediaKeySession(%p)::message", this); | 780 WTF_LOG(Media, "MediaKeySession(%p)::message", this); |
524 | 781 |
525 // Verify that 'message' not fired before session initialization is complete . | 782 // Verify that 'message' not fired before session initialization is complete . |
526 ASSERT(m_isCallable); | 783 ASSERT(m_isCallable); |
527 | 784 |
528 MediaKeyMessageEventInit init; | 785 MediaKeyMessageEventInit init; |
529 init.bubbles = false; | 786 init.bubbles = false; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
647 { | 904 { |
648 visitor->trace(m_error); | 905 visitor->trace(m_error); |
649 visitor->trace(m_asyncEventQueue); | 906 visitor->trace(m_asyncEventQueue); |
650 visitor->trace(m_pendingActions); | 907 visitor->trace(m_pendingActions); |
651 visitor->trace(m_mediaKeys); | 908 visitor->trace(m_mediaKeys); |
652 visitor->trace(m_closedPromise); | 909 visitor->trace(m_closedPromise); |
653 EventTargetWithInlineData::trace(visitor); | 910 EventTargetWithInlineData::trace(visitor); |
654 } | 911 } |
655 | 912 |
656 } // namespace blink | 913 } // namespace blink |
OLD | NEW |