void MediaKeys::timerFired(TimerBase*) { DCHECK(m_pendingActions.size()); // Swap the queue to a local copy to avoid problems if resolving promises // run synchronously. HeapDeque<Member<PendingAction>> pendingActions; pendingActions.swap(m_pendingActions); while (!pendingActions.isEmpty()) { PendingAction* action = pendingActions.takeFirst(); DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ") Certificate"; // 5.1 Let cdm be the cdm during the initialization of this object. WebContentDecryptionModule* cdm = contentDecryptionModule(); // 5.2 Use the cdm to process certificate. cdm->setServerCertificate( static_cast<unsigned char*>(action->data()->data()), action->data()->byteLength(), action->result()->result()); // 5.3 If any of the preceding steps failed, reject promise with a // new DOMException whose name is the appropriate error name. // 5.4 Resolve promise. // (These are handled by Chromium and the CDM.) } }
void MediaKeySession::actionTimerFired(Timer<MediaKeySession>*) { ASSERT(m_pendingActions.size()); // Resolving promises now run synchronously and may result in additional // actions getting added to the queue. As a result, swap the queue to // a local copy to avoid problems if this happens. HeapDeque<Member<PendingAction>> pendingActions; pendingActions.swap(m_pendingActions); while (!pendingActions.isEmpty()) { PendingAction* action = pendingActions.takeFirst(); switch (action->type()) { case PendingAction::GenerateRequest: // NOTE: Continue step 9 of MediaKeySession::generateRequest(). WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: GenerateRequest", this); // initializeNewSession() in Chromium will execute steps 9.1 to 9.7. m_session->initializeNewSession(action->initDataType(), static_cast<unsigned char*>(action->data()->data()), action->data()->byteLength(), m_sessionType, action->result()->result()); // Remaining steps (from 9.8) executed in finishGenerateRequest(), // called when |result| is resolved. break; case PendingAction::Load: // NOTE: Continue step 8 of MediaKeySession::load(). WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Load", this); // 8.1 Let sanitized session ID be a validated and/or sanitized // version of sessionId. The user agent should thoroughly // validate the sessionId value before passing it to the CDM. // At a minimum, this should include checking that the length // and value (e.g. alphanumeric) are reasonable. // 8.2 If the previous step failed, reject promise with a new // DOMException whose name is "InvalidAccessError". if (!isValidSessionId(action->sessionId())) { action->result()->completeWithError(WebContentDecryptionModuleExceptionInvalidAccessError, 0, "Invalid sessionId"); return; } // 8.3 If there is an unclosed session in the object's Document // whose sessionId attribute is sanitized session ID, reject // promise with a new DOMException whose name is // QuotaExceededError. In other words, do not create a session // if a non-closed session, regardless of type, already exists // for this sanitized session ID in this browsing context. // (Done in the CDM.) // 8.4 Let expiration time be NaN. // (Done in the constructor.) ASSERT(std::isnan(m_expiration)); // load() in Chromium will execute steps 8.5 through 8.8. m_session->load(action->sessionId(), action->result()->result()); // Remaining steps (from 8.9) executed in finishLoad(), called // when |result| is resolved. break; case PendingAction::Update: // NOTE: Continue step 5 of MediaKeySession::update(). WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Update", this); // update() in Chromium will execute steps 5.1 through 5.8. m_session->update(static_cast<unsigned char*>(action->data()->data()), action->data()->byteLength(), action->result()->result()); // Last step (5.9 Resolve promise) will be done when |result| is // resolved. break; case PendingAction::Close: // NOTE: Continue step 4 of MediaKeySession::close(). WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Close", this); // close() in Chromium will execute steps 4.1 through 4.2. m_session->close(action->result()->result()); // Last step (4.3 Resolve promise) will be done when |result| is // resolved. break; case PendingAction::Remove: // NOTE: Continue step 5 of MediaKeySession::remove(). WTF_LOG(Media, "MediaKeySession(%p)::actionTimerFired: Remove", this); // remove() in Chromium will execute steps 5.1 through 5.3. m_session->remove(action->result()->result()); // Last step (5.3.3 Resolve promise) will be done when |result| is // resolved. break; } } }