Index: content/renderer/media/crypto/proxy_decryptor.cc |
diff --git a/content/renderer/media/crypto/proxy_decryptor.cc b/content/renderer/media/crypto/proxy_decryptor.cc |
index 2c9c0085ecca3667923a96a21e0c92bbdd7136f0..b5562785045171ba7ad564053d7df173707bd89c 100644 |
--- a/content/renderer/media/crypto/proxy_decryptor.cc |
+++ b/content/renderer/media/crypto/proxy_decryptor.cc |
@@ -4,6 +4,8 @@ |
#include "content/renderer/media/crypto/proxy_decryptor.h" |
+#include <cstring> |
+ |
#include "base/bind.h" |
#include "base/callback_helpers.h" |
#include "base/logging.h" |
@@ -25,6 +27,11 @@ uint32 ProxyDecryptor::next_session_id_ = 100000; |
const uint32 kInvalidSessionId = 0; |
+// Special system code to signal a closed persistent session in a SessionError() |
+// call. This is needed because there is no SessionClosed() call in the prefixed |
+// EME API. |
+const int kSessionClosedSystemCode = 7 * 1024 * 1024 + 7; |
+ |
#if defined(ENABLE_PEPPER_CDMS) |
void ProxyDecryptor::DestroyHelperPlugin() { |
ContentDecryptionModuleFactory::DestroyHelperPlugin( |
@@ -83,30 +90,36 @@ bool ProxyDecryptor::InitializeCDM(const std::string& key_system, |
return true; |
} |
+// Returns true if |data| is prefixed with |header| and has data after the |
+// |header|. |
+bool HasHeader(const uint8* data, int data_length, const std::string& header) { |
+ return static_cast<size_t>(data_length) > header.size() && |
+ std::equal(data, data + header.size(), header.begin()); |
+} |
+ |
bool ProxyDecryptor::GenerateKeyRequest(const std::string& content_type, |
const uint8* init_data, |
int init_data_length) { |
// Use a unique reference id for this request. |
uint32 session_id = next_session_id_++; |
- const uint8 kPrefixedApiLoadSessionHeader[] = "LOAD_SESSION|"; |
- const int kPrefixedApiLoadSessionHeaderLength = |
- sizeof(kPrefixedApiLoadSessionHeader) - 1; |
+ const char kPrefixedApiPersistentSessionHeader[] = "PERSISTENT|"; |
+ const char kPrefixedApiLoadSessionHeader[] = "LOAD_SESSION|"; |
- if (init_data_length > kPrefixedApiLoadSessionHeaderLength && |
- std::equal(init_data, |
- init_data + kPrefixedApiLoadSessionHeaderLength, |
- kPrefixedApiLoadSessionHeader)) { |
- // TODO(xhwang): Track loadable session to handle OnSessionClosed(). |
- // See: http://crbug.com/340859. |
+ if (HasHeader(init_data, init_data_length, kPrefixedApiLoadSessionHeader)) { |
+ persistent_sessions_.insert(session_id); |
media_keys_->LoadSession( |
session_id, |
std::string(reinterpret_cast<const char*>( |
- init_data + kPrefixedApiLoadSessionHeaderLength), |
- init_data_length - kPrefixedApiLoadSessionHeaderLength)); |
+ init_data + strlen(kPrefixedApiLoadSessionHeader)), |
+ init_data_length - strlen(kPrefixedApiLoadSessionHeader))); |
return true; |
} |
+ if (HasHeader( |
+ init_data, init_data_length, kPrefixedApiPersistentSessionHeader)) |
+ persistent_sessions_.insert(session_id); |
+ |
return media_keys_->CreateSession( |
session_id, content_type, init_data, init_data_length); |
} |
@@ -219,7 +232,14 @@ void ProxyDecryptor::OnSessionReady(uint32 session_id) { |
} |
void ProxyDecryptor::OnSessionClosed(uint32 session_id) { |
- // No closed event in EME v0.1b. |
+ std::set<uint32>::iterator it = persistent_sessions_.find(session_id); |
+ if (it != persistent_sessions_.end()) { |
+ persistent_sessions_.erase(it); |
+ OnSessionError( |
+ session_id, media::MediaKeys::kUnknownError, kSessionClosedSystemCode); |
+ } |
+ |
+ sessions_.erase(session_id); |
} |
void ProxyDecryptor::OnSessionError(uint32 session_id, |