| 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 a10b741864515479e92f5ed23d65eb3936066c36..c69692b8ead5ac503df8633ef3d5b3c31008c317 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,85 @@ 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::MediaKeysException PpExceptionTypeToMediaException(
|
| + PP_ExceptionCodeType exception_code) {
|
| + switch (exception_code) {
|
| + case PP_EXCEPTIONCODETYPE_INDEXSIZEERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_INDEX_SIZE_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_HIERARCHYREQUESTERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_HIERARCHY_REQUEST_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_WRONGDOCUMENTERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_WRONG_DOCUMENT_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_INVALIDCHARACTERERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_INVALID_CHARACTER_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_NOMODIFICATIONALLOWEDERROR:
|
| + return media::MediaKeys::
|
| + MEDIA_KEYS_EXCEPTION_NO_MODIFICATION_ALLOWED_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_NOTFOUNDERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_NOT_FOUND_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_NOTSUPPORTEDERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_NOT_SUPPORTED_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_INVALIDSTATEERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_INVALID_STATE_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_SYNTAXERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_SYNTAX_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_INVALIDMODIFICATIONERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_INVALID_MODIFICATION_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_NAMESPACEERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_NAMESPACE_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_INVALIDACCESSERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_INVALID_ACCESS_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_SECURITYERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_SECURITY_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_NETWORKERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_NETWORK_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_ABORTERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_ABORT_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_URLMISMATCHERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_URL_MISMATCH_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_QUOTAEXCEEDEDERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_QUOTA_EXCEEDED_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_TIMEOUTERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_TIMEOUT_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_INVALIDNODETYPEERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_INVALID_NODE_TYPE_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_DATACLONEERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_DATA_CLONE_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_ENCODINGERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_ENCODING_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_NOTREADABLEERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_NOT_READABLE_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_DATAERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_DATA_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_OPERATIONERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_OPERATION_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_VERSIONERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_VERSION_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_UNKNOWNERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_UNKNOWN_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_CLIENTERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_CLIENT_ERROR;
|
| + case PP_EXCEPTIONCODETYPE_OUTPUTERROR:
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_OUTPUT_ERROR;
|
| + default:
|
| + NOTREACHED();
|
| + return media::MediaKeys::MEDIA_KEYS_EXCEPTION_SECURITY_ERROR;
|
| + }
|
| +}
|
| +
|
| } // namespace
|
|
|
| ContentDecryptorDelegate::ContentDecryptorDelegate(
|
| @@ -256,6 +336,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 +347,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 +356,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 +371,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::CdmPromise<std::string> > promise) {
|
| + uint32_t promise_id = SaveSessionPromise(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::CdmPromise<std::string> > promise) {
|
| + uint32_t promise_id = SaveSessionPromise(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::CdmPromise<void> > promise) {
|
| + uint32_t promise_id = SaveVoidPromise(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::CdmPromise<void> > promise) {
|
| + uint32_t promise_id = SaveVoidPromise(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 +664,108 @@ 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::CdmPromise<void> > promise =
|
| + RetrieveVoidPromise(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::CdmPromise<std::string> > promise =
|
| + RetrieveSessionPromise(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);
|
| +
|
| + promise->resolve(web_session_id->value());
|
| +}
|
|
|
| - session_created_cb_.Run(session_id, session_id_string->value());
|
| +void ContentDecryptorDelegate::OnPromiseRejected(
|
| + uint32 promise_id,
|
| + PP_ExceptionCodeType exception_code,
|
| + uint32 system_code,
|
| + PP_Var error_description_var) {
|
| + StringVar* error_description = StringVar::FromPPVar(error_description_var);
|
| + DCHECK(error_description);
|
| +
|
| + scoped_ptr<media::CdmPromise<std::string> > promise =
|
| + RetrieveSessionPromise(promise_id);
|
| + if (promise) {
|
| + promise->reject(PpExceptionTypeToMediaException(exception_code),
|
| + system_code,
|
| + error_description->value());
|
| + } else {
|
| + scoped_ptr<media::CdmPromise<void> > promise =
|
| + RetrieveVoidPromise(promise_id);
|
| + promise->reject(PpExceptionTypeToMediaException(exception_code),
|
| + system_code,
|
| + error_description->value());
|
| + }
|
| }
|
|
|
| -void ContentDecryptorDelegate::OnSessionMessage(uint32 session_id,
|
| +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);
|
| + StringVar* destination_url_string = StringVar::FromPPVar(destination_url_var);
|
| + DCHECK(destination_url_string);
|
|
|
| - if (!default_url_string) {
|
| - OnSessionError(session_id, media::MediaKeys::kUnknownError, 0);
|
| - return;
|
| - }
|
| -
|
| - 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_ExceptionCodeType 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(
|
| @@ -1064,4 +1195,40 @@ void ContentDecryptorDelegate::SatisfyAllPendingCallbacksOnError() {
|
| video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL);
|
| }
|
|
|
| +uint32_t ContentDecryptorDelegate::SaveVoidPromise(
|
| + scoped_ptr<media::CdmPromise<void> > promise) {
|
| + uint32_t promise_id = ++next_promise_id_;
|
| + void_promises_.insert(std::make_pair(promise_id, promise.release()));
|
| + return promise_id;
|
| +}
|
| +
|
| +scoped_ptr<media::CdmPromise<void> >
|
| +ContentDecryptorDelegate::RetrieveVoidPromise(uint32_t promise_id) {
|
| + std::map<uint32_t, media::CdmPromise<void>*>::iterator it =
|
| + void_promises_.find(promise_id);
|
| + if (it == void_promises_.end())
|
| + return scoped_ptr<media::CdmPromise<void> >();
|
| + scoped_ptr<media::CdmPromise<void> > result(it->second);
|
| + void_promises_.erase(it);
|
| + return result.Pass();
|
| +}
|
| +
|
| +uint32_t ContentDecryptorDelegate::SaveSessionPromise(
|
| + scoped_ptr<media::CdmPromise<std::string> > promise) {
|
| + uint32_t promise_id = ++next_promise_id_;
|
| + session_promises_.insert(std::make_pair(promise_id, promise.release()));
|
| + return promise_id;
|
| +}
|
| +
|
| +scoped_ptr<media::CdmPromise<std::string> >
|
| +ContentDecryptorDelegate::RetrieveSessionPromise(uint32_t promise_id) {
|
| + std::map<uint32_t, media::CdmPromise<std::string>*>::iterator it =
|
| + session_promises_.find(promise_id);
|
| + if (it == session_promises_.end())
|
| + return scoped_ptr<media::CdmPromise<std::string> >();
|
| + scoped_ptr<media::CdmPromise<std::string> > result(it->second);
|
| + session_promises_.erase(it);
|
| + return result.Pass();
|
| +}
|
| +
|
| } // namespace content
|
|
|