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

Unified Diff: content/renderer/media/crypto/proxy_decryptor.cc

Issue 265993002: Add Promises for EME (Chromium side) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: One more trybot issue Created 6 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/renderer/media/crypto/proxy_decryptor.h ('k') | content/renderer/media/crypto/proxy_media_keys.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 be9893b584e57bf93b073fc8d2bce29f933e13de..7d790706f1a7ca979651ddfbb210b8991fed8793 100644
--- a/content/renderer/media/crypto/proxy_decryptor.cc
+++ b/content/renderer/media/crypto/proxy_decryptor.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "content/renderer/media/crypto/content_decryption_module_factory.h"
+#include "media/base/cdm_promise.h"
#include "media/cdm/json_web_key.h"
#include "media/cdm/key_system_names.h"
@@ -24,14 +25,6 @@
namespace content {
-// Since these reference IDs may conflict with the ones generated in
-// WebContentDecryptionModuleSessionImpl for the short time both paths are
-// active, start with 100000 and generate the IDs from there.
-// TODO(jrummell): Only allow one path http://crbug.com/306680.
-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.
@@ -105,28 +98,39 @@ bool HasHeader(const uint8* data, int data_length, const std::string& header) {
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_++;
-
+ DVLOG(1) << "GenerateKeyRequest()";
const char kPrefixedApiPersistentSessionHeader[] = "PERSISTENT|";
const char kPrefixedApiLoadSessionHeader[] = "LOAD_SESSION|";
- if (HasHeader(init_data, init_data_length, kPrefixedApiLoadSessionHeader)) {
- persistent_sessions_.insert(session_id);
+ bool loadSession =
+ HasHeader(init_data, init_data_length, kPrefixedApiLoadSessionHeader);
+ bool persistent = HasHeader(
+ init_data, init_data_length, kPrefixedApiPersistentSessionHeader);
+
+ scoped_ptr<media::NewSessionCdmPromise> promise(
+ new media::NewSessionCdmPromise(
+ base::Bind(&ProxyDecryptor::SetSessionId,
+ weak_ptr_factory_.GetWeakPtr(),
+ persistent || loadSession),
+ base::Bind(&ProxyDecryptor::OnSessionError,
+ weak_ptr_factory_.GetWeakPtr(),
+ std::string()))); // No session id until created.
+
+ if (loadSession) {
media_keys_->LoadSession(
- session_id,
std::string(reinterpret_cast<const char*>(
init_data + strlen(kPrefixedApiLoadSessionHeader)),
- init_data_length - strlen(kPrefixedApiLoadSessionHeader)));
+ init_data_length - strlen(kPrefixedApiLoadSessionHeader)),
+ promise.Pass());
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);
+ media::MediaKeys::SessionType session_type =
+ persistent ? media::MediaKeys::PERSISTENT_SESSION
+ : media::MediaKeys::TEMPORARY_SESSION;
+ media_keys_->CreateSession(
+ content_type, init_data, init_data_length, session_type, promise.Pass());
+ return true;
}
void ProxyDecryptor::AddKey(const uint8* key,
@@ -136,18 +140,31 @@ void ProxyDecryptor::AddKey(const uint8* key,
const std::string& web_session_id) {
DVLOG(1) << "AddKey()";
- // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called.
- uint32 session_id = LookupSessionId(web_session_id);
- if (session_id == kInvalidSessionId) {
- // Session hasn't been referenced before, so it is an error.
- // Note that the specification says "If sessionId is not null and is
- // unrecognized, throw an INVALID_ACCESS_ERR." However, for backwards
- // compatibility the error is not thrown, but rather reported as a
- // KeyError.
- key_error_cb_.Run(std::string(), media::MediaKeys::kUnknownError, 0);
- return;
+ // In the prefixed API, the session parameter provided to addKey() is
+ // optional, so use the single existing session if it exists.
+ // TODO(jrummell): remove when the prefixed API is removed.
+ std::string session_id(web_session_id);
+ if (session_id.empty()) {
+ if (active_sessions_.size() == 1) {
+ base::hash_map<std::string, bool>::iterator it = active_sessions_.begin();
+ session_id = it->first;
+ } else {
+ OnSessionError(std::string(),
+ media::MediaKeys::NOT_SUPPORTED_ERROR,
+ 0,
+ "SessionId not specified.");
+ return;
+ }
}
+ scoped_ptr<media::SimpleCdmPromise> promise(
+ new media::SimpleCdmPromise(base::Bind(&ProxyDecryptor::OnSessionReady,
+ weak_ptr_factory_.GetWeakPtr(),
+ web_session_id),
+ base::Bind(&ProxyDecryptor::OnSessionError,
+ weak_ptr_factory_.GetWeakPtr(),
+ web_session_id)));
+
// EME WD spec only supports a single array passed to the CDM. For
// Clear Key using v0.1b, both arrays are used (|init_data| is key_id).
// Since the EME WD spec supports the key as a JSON Web Key,
@@ -164,27 +181,27 @@ void ProxyDecryptor::AddKey(const uint8* key,
std::string jwk =
media::GenerateJWKSet(key, key_length, init_data, init_data_length);
DCHECK(!jwk.empty());
- media_keys_->UpdateSession(
- session_id, reinterpret_cast<const uint8*>(jwk.data()), jwk.size());
+ media_keys_->UpdateSession(session_id,
+ reinterpret_cast<const uint8*>(jwk.data()),
+ jwk.size(),
+ promise.Pass());
return;
}
- media_keys_->UpdateSession(session_id, key, key_length);
+ media_keys_->UpdateSession(session_id, key, key_length, promise.Pass());
}
-void ProxyDecryptor::CancelKeyRequest(const std::string& session_id) {
+void ProxyDecryptor::CancelKeyRequest(const std::string& web_session_id) {
DVLOG(1) << "CancelKeyRequest()";
- // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called.
- uint32 session_reference_id = LookupSessionId(session_id);
- if (session_reference_id == kInvalidSessionId) {
- // Session hasn't been created, so it is an error.
- key_error_cb_.Run(
- std::string(), media::MediaKeys::kUnknownError, 0);
- }
- else {
- media_keys_->ReleaseSession(session_reference_id);
- }
+ scoped_ptr<media::SimpleCdmPromise> promise(
+ new media::SimpleCdmPromise(base::Bind(&ProxyDecryptor::OnSessionClosed,
+ weak_ptr_factory_.GetWeakPtr(),
+ web_session_id),
+ base::Bind(&ProxyDecryptor::OnSessionError,
+ weak_ptr_factory_.GetWeakPtr(),
+ web_session_id)));
+ media_keys_->ReleaseSession(web_session_id, promise.Pass());
}
scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys(
@@ -199,8 +216,6 @@ scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys(
manager_,
&cdm_id_,
#endif // defined(ENABLE_PEPPER_CDMS)
- base::Bind(&ProxyDecryptor::OnSessionCreated,
- weak_ptr_factory_.GetWeakPtr()),
base::Bind(&ProxyDecryptor::OnSessionMessage,
weak_ptr_factory_.GetWeakPtr()),
base::Bind(&ProxyDecryptor::OnSessionReady,
@@ -211,68 +226,56 @@ scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys(
weak_ptr_factory_.GetWeakPtr()));
}
-void ProxyDecryptor::OnSessionCreated(uint32 session_id,
- const std::string& web_session_id) {
- // Due to heartbeat messages, OnSessionCreated() can get called multiple
- // times.
- SessionIdMap::iterator it = sessions_.find(session_id);
- DCHECK(it == sessions_.end() || it->second == web_session_id);
- if (it == sessions_.end())
- sessions_[session_id] = web_session_id;
-}
-
-void ProxyDecryptor::OnSessionMessage(uint32 session_id,
+void ProxyDecryptor::OnSessionMessage(const std::string& web_session_id,
const std::vector<uint8>& message,
const GURL& destination_url) {
// Assumes that OnSessionCreated() has been called before this.
- key_message_cb_.Run(
- LookupWebSessionId(session_id), message, destination_url);
+ key_message_cb_.Run(web_session_id, message, destination_url);
}
-void ProxyDecryptor::OnSessionReady(uint32 session_id) {
- // Assumes that OnSessionCreated() has been called before this.
- key_added_cb_.Run(LookupWebSessionId(session_id));
+void ProxyDecryptor::OnSessionReady(const std::string& web_session_id) {
+ key_added_cb_.Run(web_session_id);
}
-void ProxyDecryptor::OnSessionClosed(uint32 session_id) {
- 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);
+void ProxyDecryptor::OnSessionClosed(const std::string& web_session_id) {
+ base::hash_map<std::string, bool>::iterator it =
+ active_sessions_.find(web_session_id);
+ if (it->second) {
+ OnSessionError(web_session_id,
+ media::MediaKeys::NOT_SUPPORTED_ERROR,
+ kSessionClosedSystemCode,
+ "Do not close persistent sessions.");
}
-
- sessions_.erase(session_id);
-}
-
-void ProxyDecryptor::OnSessionError(uint32 session_id,
- media::MediaKeys::KeyError error_code,
- uint32 system_code) {
- // Assumes that OnSessionCreated() has been called before this.
- key_error_cb_.Run(LookupWebSessionId(session_id), error_code, system_code);
+ active_sessions_.erase(it);
}
-uint32 ProxyDecryptor::LookupSessionId(const std::string& session_id) const {
- for (SessionIdMap::const_iterator it = sessions_.begin();
- it != sessions_.end();
- ++it) {
- if (it->second == session_id)
- return it->first;
+void ProxyDecryptor::OnSessionError(const std::string& web_session_id,
+ media::MediaKeys::Exception exception_code,
+ uint32 system_code,
+ const std::string& error_message) {
+ // Convert |error_name| back to MediaKeys::KeyError if possible. Prefixed
+ // EME has different error message, so all the specific error events will
+ // get lost.
+ media::MediaKeys::KeyError error_code;
+ switch (exception_code) {
+ case media::MediaKeys::CLIENT_ERROR:
+ error_code = media::MediaKeys::kClientError;
+ break;
+ case media::MediaKeys::OUTPUT_ERROR:
+ error_code = media::MediaKeys::kOutputError;
+ break;
+ default:
+ // This will include all other CDM4 errors and any error generated
+ // by CDM5 or later.
+ error_code = media::MediaKeys::kUnknownError;
+ break;
}
-
- // If |session_id| is null, then use the single reference id.
- if (session_id.empty() && sessions_.size() == 1)
- return sessions_.begin()->first;
-
- return kInvalidSessionId;
+ key_error_cb_.Run(web_session_id, error_code, system_code);
}
-const std::string& ProxyDecryptor::LookupWebSessionId(uint32 session_id) const {
- DCHECK_NE(session_id, kInvalidSessionId);
-
- // Session may not exist if error happens during GenerateKeyRequest().
- SessionIdMap::const_iterator it = sessions_.find(session_id);
- return (it != sessions_.end()) ? it->second : base::EmptyString();
+void ProxyDecryptor::SetSessionId(bool persistent,
+ const std::string& web_session_id) {
+ active_sessions_.insert(std::make_pair(web_session_id, persistent));
}
} // namespace content
« no previous file with comments | « content/renderer/media/crypto/proxy_decryptor.h ('k') | content/renderer/media/crypto/proxy_media_keys.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698