| Index: media/cdm/aes_decryptor.cc
|
| diff --git a/media/cdm/aes_decryptor.cc b/media/cdm/aes_decryptor.cc
|
| index 8621584f3cc37dfdd3aa1ea4b779152c0342731b..3f41e2941a9375239711bd1da2254b9f6e5895dd 100644
|
| --- a/media/cdm/aes_decryptor.cc
|
| +++ b/media/cdm/aes_decryptor.cc
|
| @@ -261,7 +261,7 @@ void AesDecryptor::CreateSessionAndGenerateRequest(
|
| const std::vector<uint8_t>& init_data,
|
| std::unique_ptr<NewSessionCdmPromise> promise) {
|
| std::string session_id(base::UintToString(next_session_id_++));
|
| - valid_sessions_.insert(session_id);
|
| + open_sessions_.insert(session_id);
|
|
|
| // For now, the AesDecryptor does not care about |session_type|.
|
| // TODO(jrummell): Validate |session_type|.
|
| @@ -329,8 +329,11 @@ void AesDecryptor::UpdateSession(const std::string& session_id,
|
| std::unique_ptr<SimpleCdmPromise> promise) {
|
| CHECK(!response.empty());
|
|
|
| - // TODO(jrummell): Convert back to a DCHECK once prefixed EME is removed.
|
| - if (valid_sessions_.find(session_id) == valid_sessions_.end()) {
|
| + // Currently the EME spec has blink check for session closed synchronously,
|
| + // but then this is called asynchronously. So it is possible that update()
|
| + // could get called on a closed session.
|
| + // https://github.com/w3c/encrypted-media/issues/365
|
| + if (open_sessions_.find(session_id) == open_sessions_.end()) {
|
| promise->reject(CdmPromise::INVALID_ACCESS_ERROR, 0,
|
| "Session does not exist.");
|
| return;
|
| @@ -405,14 +408,25 @@ void AesDecryptor::UpdateSession(const std::string& session_id,
|
| // Runs the parallel steps from https://w3c.github.io/encrypted-media/#close.
|
| void AesDecryptor::CloseSession(const std::string& session_id,
|
| std::unique_ptr<SimpleCdmPromise> promise) {
|
| - // Validate that this is a reference to an active session and then forget it.
|
| - std::set<std::string>::iterator it = valid_sessions_.find(session_id);
|
| - DCHECK(it != valid_sessions_.end());
|
| + // Validate that this is a reference to an open session. close() shouldn't
|
| + // be called if the session is already closed. However, the operation is
|
| + // asynchronous, so there is a window where close() was called a second time
|
| + // just before the closed event arrives. As a result it is possible that the
|
| + // session is already closed, so assume that the session is closed if it
|
| + // doesn't exist. https://github.com/w3c/encrypted-media/issues/365.
|
| + //
|
| + // close() is called from a MediaKeySession object, so it is unlikely that
|
| + // this method will be called with a previously unseen |session_id|.
|
| + std::set<std::string>::iterator it = open_sessions_.find(session_id);
|
| + if (it == open_sessions_.end()) {
|
| + promise->resolve();
|
| + return;
|
| + }
|
|
|
| // 5.1. Let cdm be the CDM instance represented by session's cdm instance
|
| // value.
|
| // 5.2. Use cdm to close the session associated with session.
|
| - valid_sessions_.erase(it);
|
| + open_sessions_.erase(it);
|
| DeleteKeysForSession(session_id);
|
|
|
| // 5.3. Queue a task to run the following steps:
|
|
|