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

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

Powered by Google App Engine
This is Rietveld 408576698