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

Unified Diff: content/renderer/pepper/content_decryptor_delegate.cc

Issue 265993002: Add Promises for EME (Chromium side) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: updates Created 6 years, 7 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
Index: content/renderer/pepper/content_decryptor_delegate.cc
diff --git a/content/renderer/pepper/content_decryptor_delegate.cc b/content/renderer/pepper/content_decryptor_delegate.cc
index a36cf6f353965d041c421e3f538bd81c708c6b0b..52bab56320a49af90ffc3a596eed605b33ed528f 100644
--- a/content/renderer/pepper/content_decryptor_delegate.cc
+++ b/content/renderer/pepper/content_decryptor_delegate.cc
@@ -12,6 +12,7 @@
#include "media/base/audio_buffer.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/bind_to_current_loop.h"
+#include "media/base/cdm_promise.h"
#include "media/base/channel_layout.h"
#include "media/base/data_buffer.h"
#include "media/base/decoder_buffer.h"
@@ -245,6 +246,64 @@ media::SampleFormat PpDecryptedSampleFormatToMediaSampleFormat(
}
}
+PP_SessionType MediaSessionTypeToPpSessionType(
+ media::MediaKeys::SessionType session_type) {
+ switch (session_type) {
+ case media::MediaKeys::SESSION_TYPE_TEMPORARY:
+ return PP_SESSIONTYPE_TEMPORARY;
+ case media::MediaKeys::SESSION_TYPE_PERSISTENT:
+ return PP_SESSIONTYPE_PERSISTENT;
+ default:
+ NOTREACHED();
+ return PP_SESSIONTYPE_TEMPORARY;
+ }
+}
+
+media::MediaKeys::Exception PpExceptionTypeToMediaException(
+ PP_ExceptionCode exception_code) {
+ switch (exception_code) {
+ case PP_EXCEPTIONCODE_NOMODIFICATIONALLOWEDERROR:
+ return media::MediaKeys::EXCEPTION_NO_MODIFICATION_ALLOWED_ERROR;
+ case PP_EXCEPTIONCODE_NOTFOUNDERROR:
+ return media::MediaKeys::EXCEPTION_NOT_FOUND_ERROR;
+ case PP_EXCEPTIONCODE_NOTSUPPORTEDERROR:
+ return media::MediaKeys::EXCEPTION_NOT_SUPPORTED_ERROR;
+ case PP_EXCEPTIONCODE_INVALIDSTATEERROR:
+ return media::MediaKeys::EXCEPTION_INVALID_STATE_ERROR;
+ case PP_EXCEPTIONCODE_SYNTAXERROR:
ddorwin 2014/05/15 23:15:32 Let's not support this in Pepper (and remove from
jrummell 2014/05/16 00:49:53 Done.
+ return media::MediaKeys::EXCEPTION_SYNTAX_ERROR;
+ case PP_EXCEPTIONCODE_INVALIDMODIFICATIONERROR:
+ return media::MediaKeys::EXCEPTION_INVALID_MODIFICATION_ERROR;
+ case PP_EXCEPTIONCODE_INVALIDACCESSERROR:
+ return media::MediaKeys::EXCEPTION_INVALID_ACCESS_ERROR;
+ case PP_EXCEPTIONCODE_SECURITYERROR:
+ return media::MediaKeys::EXCEPTION_SECURITY_ERROR;
+ case PP_EXCEPTIONCODE_ABORTERROR:
+ return media::MediaKeys::EXCEPTION_ABORT_ERROR;
+ case PP_EXCEPTIONCODE_QUOTAEXCEEDEDERROR:
+ return media::MediaKeys::EXCEPTION_QUOTA_EXCEEDED_ERROR;
+ case PP_EXCEPTIONCODE_TIMEOUTERROR:
+ return media::MediaKeys::EXCEPTION_TIMEOUT_ERROR;
+ case PP_EXCEPTIONCODE_UNKNOWNERROR:
+ return media::MediaKeys::EXCEPTION_UNKNOWN_ERROR;
+ case PP_EXCEPTIONCODE_DATAERROR:
+ return media::MediaKeys::EXCEPTION_DATA_ERROR;
+ case PP_EXCEPTIONCODE_VERSIONERROR:
+ return media::MediaKeys::EXCEPTION_VERSION_ERROR;
+ case PP_EXCEPTIONCODE_NOTREADABLEERROR:
+ return media::MediaKeys::EXCEPTION_NOT_READABLE_ERROR;
+ case PP_EXCEPTIONCODE_OPERATIONERROR:
+ return media::MediaKeys::EXCEPTION_OPERATION_ERROR;
+ case PP_EXCEPTIONCODE_CLIENTERROR:
+ return media::MediaKeys::EXCEPTION_CLIENT_ERROR;
+ case PP_EXCEPTIONCODE_OUTPUTERROR:
+ return media::MediaKeys::EXCEPTION_OUTPUT_ERROR;
+ default:
+ NOTREACHED();
+ return media::MediaKeys::EXCEPTION_UNKNOWN_ERROR;
+ }
+}
+
} // namespace
ContentDecryptorDelegate::ContentDecryptorDelegate(
@@ -256,6 +315,7 @@ ContentDecryptorDelegate::ContentDecryptorDelegate(
audio_samples_per_second_(0),
audio_channel_count_(0),
audio_channel_layout_(media::CHANNEL_LAYOUT_NONE),
+ next_promise_id_(0),
weak_ptr_factory_(this) {
weak_this_ = weak_ptr_factory_.GetWeakPtr();
}
@@ -266,7 +326,6 @@ ContentDecryptorDelegate::~ContentDecryptorDelegate() {
void ContentDecryptorDelegate::Initialize(
const std::string& key_system,
- const media::SessionCreatedCB& session_created_cb,
const media::SessionMessageCB& session_message_cb,
const media::SessionReadyCB& session_ready_cb,
const media::SessionClosedCB& session_closed_cb,
@@ -276,7 +335,6 @@ void ContentDecryptorDelegate::Initialize(
DCHECK(key_system_.empty());
key_system_ = key_system;
- session_created_cb_ = session_created_cb;
session_message_cb_ = session_message_cb;
session_ready_cb_ = session_ready_cb;
session_closed_cb_ = session_closed_cb;
@@ -292,42 +350,54 @@ void ContentDecryptorDelegate::InstanceCrashed() {
SatisfyAllPendingCallbacksOnError();
}
-bool ContentDecryptorDelegate::CreateSession(uint32 session_id,
- const std::string& content_type,
- const uint8* init_data,
- int init_data_length) {
+void ContentDecryptorDelegate::CreateSession(
+ const std::string& init_data_type,
+ const uint8* init_data,
+ int init_data_length,
+ media::MediaKeys::SessionType session_type,
+ scoped_ptr<media::NewSessionCdmPromise> promise) {
+ uint32_t promise_id = SaveNewSessionPromise(promise.Pass());
PP_Var init_data_array =
PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
init_data_length, init_data);
-
plugin_decryption_interface_->CreateSession(
pp_instance_,
- session_id,
- StringVar::StringToPPVar(content_type),
- init_data_array);
- return true;
+ promise_id,
+ StringVar::StringToPPVar(init_data_type),
+ init_data_array,
+ MediaSessionTypeToPpSessionType(session_type));
}
-void ContentDecryptorDelegate::LoadSession(uint32 session_id,
- const std::string& web_session_id) {
+void ContentDecryptorDelegate::LoadSession(
+ const std::string& web_session_id,
+ scoped_ptr<media::NewSessionCdmPromise> promise) {
+ uint32_t promise_id = SaveNewSessionPromise(promise.Pass());
plugin_decryption_interface_->LoadSession(
- pp_instance_, session_id, StringVar::StringToPPVar(web_session_id));
+ pp_instance_, promise_id, StringVar::StringToPPVar(web_session_id));
}
-bool ContentDecryptorDelegate::UpdateSession(uint32 session_id,
- const uint8* response,
- int response_length) {
+void ContentDecryptorDelegate::UpdateSession(
+ const std::string& web_session_id,
+ const uint8* response,
+ int response_length,
+ scoped_ptr<media::SimpleCdmPromise> promise) {
+ uint32_t promise_id = SaveSimplePromise(promise.Pass());
PP_Var response_array =
PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
response_length, response);
plugin_decryption_interface_->UpdateSession(
- pp_instance_, session_id, response_array);
- return true;
+ pp_instance_,
+ promise_id,
+ StringVar::StringToPPVar(web_session_id),
+ response_array);
}
-bool ContentDecryptorDelegate::ReleaseSession(uint32 session_id) {
- plugin_decryption_interface_->ReleaseSession(pp_instance_, session_id);
- return true;
+void ContentDecryptorDelegate::ReleaseSession(
+ const std::string& web_session_id,
+ scoped_ptr<media::SimpleCdmPromise> promise) {
+ uint32_t promise_id = SaveSimplePromise(promise.Pass());
+ plugin_decryption_interface_->ReleaseSession(
+ pp_instance_, promise_id, StringVar::StringToPPVar(web_session_id));
}
// TODO(xhwang): Remove duplication of code in Decrypt(),
@@ -573,68 +643,105 @@ bool ContentDecryptorDelegate::DecryptAndDecodeVideo(
return true;
}
-void ContentDecryptorDelegate::OnSessionCreated(uint32 session_id,
- PP_Var web_session_id_var) {
- if (session_created_cb_.is_null())
- return;
+void ContentDecryptorDelegate::OnPromiseResolved(uint32 promise_id) {
+ scoped_ptr<media::SimpleCdmPromise> promise = TakeSimplePromise(promise_id);
+ promise->resolve();
+}
- StringVar* session_id_string = StringVar::FromPPVar(web_session_id_var);
+void ContentDecryptorDelegate::OnPromiseResolvedWithSession(
+ uint32 promise_id,
+ PP_Var web_session_id_var) {
+ scoped_ptr<media::NewSessionCdmPromise> promise =
+ TakeNewSessionPromise(promise_id);
- if (!session_id_string) {
- OnSessionError(session_id, media::MediaKeys::kUnknownError, 0);
- return;
- }
+ StringVar* web_session_id = StringVar::FromPPVar(web_session_id_var);
+ DCHECK(web_session_id);
- session_created_cb_.Run(session_id, session_id_string->value());
+ promise->resolve(web_session_id->value());
}
-void ContentDecryptorDelegate::OnSessionMessage(uint32 session_id,
+void ContentDecryptorDelegate::OnPromiseRejected(
+ uint32 promise_id,
+ PP_ExceptionCode exception_code,
+ uint32 system_code,
+ PP_Var error_description_var) {
+ StringVar* error_description = StringVar::FromPPVar(error_description_var);
+ DCHECK(error_description);
+
+ scoped_ptr<media::NewSessionCdmPromise> promise =
+ TakeNewSessionPromise(promise_id);
+ if (promise) {
+ promise->reject(PpExceptionTypeToMediaException(exception_code),
+ system_code,
+ error_description->value());
+ } else {
+ scoped_ptr<media::SimpleCdmPromise> promise = TakeSimplePromise(promise_id);
+ promise->reject(PpExceptionTypeToMediaException(exception_code),
+ system_code,
+ error_description->value());
+ }
+}
+
+void ContentDecryptorDelegate::OnSessionMessage(PP_Var web_session_id_var,
PP_Var message_var,
- PP_Var default_url_var) {
+ PP_Var destination_url_var) {
if (session_message_cb_.is_null())
return;
- ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message_var);
+ StringVar* web_session_id = StringVar::FromPPVar(web_session_id_var);
+ DCHECK(web_session_id);
+ ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message_var);
std::vector<uint8> message;
if (message_array_buffer) {
const uint8* data = static_cast<const uint8*>(message_array_buffer->Map());
message.assign(data, data + message_array_buffer->ByteLength());
}
- StringVar* default_url_string = StringVar::FromPPVar(default_url_var);
-
- if (!default_url_string) {
- OnSessionError(session_id, media::MediaKeys::kUnknownError, 0);
- return;
- }
+ StringVar* destination_url_string = StringVar::FromPPVar(destination_url_var);
+ DCHECK(destination_url_string);
- session_message_cb_.Run(session_id, message, default_url_string->value());
+ session_message_cb_.Run(
+ web_session_id->value(), message, destination_url_string->value());
}
-void ContentDecryptorDelegate::OnSessionReady(uint32 session_id) {
+void ContentDecryptorDelegate::OnSessionReady(PP_Var web_session_id_var) {
if (session_ready_cb_.is_null())
return;
- session_ready_cb_.Run(session_id);
+ StringVar* web_session_id = StringVar::FromPPVar(web_session_id_var);
+ DCHECK(web_session_id);
+
+ session_ready_cb_.Run(web_session_id->value());
}
-void ContentDecryptorDelegate::OnSessionClosed(uint32 session_id) {
+void ContentDecryptorDelegate::OnSessionClosed(PP_Var web_session_id_var) {
if (session_closed_cb_.is_null())
return;
- session_closed_cb_.Run(session_id);
+ StringVar* web_session_id = StringVar::FromPPVar(web_session_id_var);
+ DCHECK(web_session_id);
+
+ session_closed_cb_.Run(web_session_id->value());
}
-void ContentDecryptorDelegate::OnSessionError(uint32 session_id,
- int32_t media_error,
- uint32_t system_code) {
+void ContentDecryptorDelegate::OnSessionError(PP_Var web_session_id_var,
+ PP_ExceptionCode exception_code,
+ uint32 system_code,
+ PP_Var error_description_var) {
if (session_error_cb_.is_null())
return;
- session_error_cb_.Run(session_id,
- static_cast<media::MediaKeys::KeyError>(media_error),
- system_code);
+ StringVar* web_session_id = StringVar::FromPPVar(web_session_id_var);
+ DCHECK(web_session_id);
+
+ StringVar* error_description = StringVar::FromPPVar(error_description_var);
+ DCHECK(error_description);
+
+ session_error_cb_.Run(web_session_id->value(),
+ PpExceptionTypeToMediaException(exception_code),
+ system_code,
+ error_description->value());
}
void ContentDecryptorDelegate::DecoderInitializeDone(
@@ -1060,6 +1167,47 @@ void ContentDecryptorDelegate::SatisfyAllPendingCallbacksOnError() {
if (!video_decode_cb_.is_null())
video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL);
+
+ // TODO(jrummell): Reject all outstanding promises. Currently some tests
+ // (ECKEncryptedMediaTest.CDMExpectedCrash and CDMCrashDuringDecode)
+ // trigger a crash in the CDM, and don't handle the response to the pending
+ // request. Once blink:: uses promises, this will be required.
+}
+
+uint32_t ContentDecryptorDelegate::SaveSimplePromise(
+ scoped_ptr<media::SimpleCdmPromise> promise) {
+ uint32_t promise_id = ++next_promise_id_;
+ void_promises_.insert(std::make_pair(promise_id, promise.release()));
+ return promise_id;
+}
+
+scoped_ptr<media::SimpleCdmPromise> ContentDecryptorDelegate::TakeSimplePromise(
+ uint32_t promise_id) {
+ std::map<uint32_t, media::SimpleCdmPromise*>::iterator it =
+ void_promises_.find(promise_id);
+ if (it == void_promises_.end())
+ return scoped_ptr<media::SimpleCdmPromise>();
+ scoped_ptr<media::SimpleCdmPromise> result(it->second);
+ void_promises_.erase(it);
+ return result.Pass();
+}
+
+uint32_t ContentDecryptorDelegate::SaveNewSessionPromise(
+ scoped_ptr<media::NewSessionCdmPromise> promise) {
+ uint32_t promise_id = ++next_promise_id_;
+ session_promises_.insert(std::make_pair(promise_id, promise.release()));
+ return promise_id;
+}
+
+scoped_ptr<media::NewSessionCdmPromise>
+ContentDecryptorDelegate::TakeNewSessionPromise(uint32_t promise_id) {
+ std::map<uint32_t, media::NewSessionCdmPromise*>::iterator it =
+ session_promises_.find(promise_id);
+ if (it == session_promises_.end())
+ return scoped_ptr<media::NewSessionCdmPromise>();
+ scoped_ptr<media::NewSessionCdmPromise> result(it->second);
+ session_promises_.erase(it);
+ return result.Pass();
}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698