| Index: content/renderer/media/crypto/ppapi_decryptor.cc
|
| diff --git a/content/renderer/media/crypto/ppapi_decryptor.cc b/content/renderer/media/crypto/ppapi_decryptor.cc
|
| index 76d0203aed9696d4424051b4223737a6c8ae55cf..4db3d0cb1be5dc0bc87b6d421934b6f40d31586c 100644
|
| --- a/content/renderer/media/crypto/ppapi_decryptor.cc
|
| +++ b/content/renderer/media/crypto/ppapi_decryptor.cc
|
| @@ -18,16 +18,63 @@
|
| #include "media/base/audio_decoder_config.h"
|
| #include "media/base/data_buffer.h"
|
| #include "media/base/decoder_buffer.h"
|
| +#include "media/base/media_keys_session_promise.h"
|
| #include "media/base/video_decoder_config.h"
|
| #include "media/base/video_frame.h"
|
|
|
| namespace content {
|
|
|
| +// This class is need so that resolving an Update() promise triggers playback
|
| +// of the stream.
|
| +class SessionUpdatedPromise : public media::MediaKeysSessionPromise {
|
| + public:
|
| + SessionUpdatedPromise(
|
| + scoped_ptr<media::MediaKeysSessionPromise> caller_promise,
|
| + media::PromiseResolvedCB resolve_cb);
|
| + virtual ~SessionUpdatedPromise();
|
| + virtual void resolve() OVERRIDE;
|
| + virtual void resolve(const std::string& web_session_id) OVERRIDE;
|
| + virtual void reject(const std::string& error_name,
|
| + uint32 system_code,
|
| + const std::string& error_message) OVERRIDE;
|
| +
|
| + protected:
|
| + scoped_ptr<media::MediaKeysSessionPromise> caller_promise_;
|
| + media::PromiseResolvedCB resolve_cb_;
|
| +};
|
| +
|
| +SessionUpdatedPromise::SessionUpdatedPromise(
|
| + scoped_ptr<media::MediaKeysSessionPromise> caller_promise,
|
| + media::PromiseResolvedCB resolve_cb)
|
| + : caller_promise_(caller_promise.Pass()),
|
| + resolve_cb_(resolve_cb) {
|
| +}
|
| +
|
| +SessionUpdatedPromise::~SessionUpdatedPromise() {
|
| +}
|
| +
|
| +void SessionUpdatedPromise::resolve() {
|
| + resolve_cb_.Run();
|
| + caller_promise_->resolve();
|
| + caller_promise_.reset();
|
| +}
|
| +
|
| +void SessionUpdatedPromise::resolve(const std::string& web_session_id) {
|
| + NOTREACHED();
|
| + caller_promise_->resolve(web_session_id);
|
| + caller_promise_.reset();
|
| +}
|
| +void SessionUpdatedPromise::reject(const std::string& error_name,
|
| + uint32 system_code,
|
| + const std::string& error_message) {
|
| + caller_promise_->reject(error_name, system_code, error_message);
|
| + caller_promise_.reset();
|
| +}
|
| +
|
| scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create(
|
| const std::string& key_system,
|
| const GURL& security_origin,
|
| const CreatePepperCdmCB& create_pepper_cdm_cb,
|
| - const media::SessionCreatedCB& session_created_cb,
|
| const media::SessionMessageCB& session_message_cb,
|
| const media::SessionReadyCB& session_ready_cb,
|
| const media::SessionClosedCB& session_closed_cb,
|
| @@ -44,7 +91,6 @@ scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create(
|
| return scoped_ptr<PpapiDecryptor>(
|
| new PpapiDecryptor(key_system,
|
| pepper_cdm_wrapper.Pass(),
|
| - session_created_cb,
|
| session_message_cb,
|
| session_ready_cb,
|
| session_closed_cb,
|
| @@ -54,13 +100,11 @@ scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create(
|
| PpapiDecryptor::PpapiDecryptor(
|
| const std::string& key_system,
|
| scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper,
|
| - const media::SessionCreatedCB& session_created_cb,
|
| const media::SessionMessageCB& session_message_cb,
|
| const media::SessionReadyCB& session_ready_cb,
|
| const media::SessionClosedCB& session_closed_cb,
|
| const media::SessionErrorCB& session_error_cb)
|
| : pepper_cdm_wrapper_(pepper_cdm_wrapper.Pass()),
|
| - session_created_cb_(session_created_cb),
|
| session_message_cb_(session_message_cb),
|
| session_ready_cb_(session_ready_cb),
|
| session_closed_cb_(session_closed_cb),
|
| @@ -68,7 +112,6 @@ PpapiDecryptor::PpapiDecryptor(
|
| render_loop_proxy_(base::MessageLoopProxy::current()),
|
| weak_ptr_factory_(this) {
|
| DCHECK(pepper_cdm_wrapper_.get());
|
| - DCHECK(!session_created_cb_.is_null());
|
| DCHECK(!session_message_cb_.is_null());
|
| DCHECK(!session_ready_cb_.is_null());
|
| DCHECK(!session_closed_cb_.is_null());
|
| @@ -77,7 +120,6 @@ PpapiDecryptor::PpapiDecryptor(
|
| base::WeakPtr<PpapiDecryptor> weak_this = weak_ptr_factory_.GetWeakPtr();
|
| CdmDelegate()->Initialize(
|
| key_system,
|
| - base::Bind(&PpapiDecryptor::OnSessionCreated, weak_this),
|
| base::Bind(&PpapiDecryptor::OnSessionMessage, weak_this),
|
| base::Bind(&PpapiDecryptor::OnSessionReady, weak_this),
|
| base::Bind(&PpapiDecryptor::OnSessionClosed, weak_this),
|
| @@ -89,57 +131,79 @@ PpapiDecryptor::~PpapiDecryptor() {
|
| pepper_cdm_wrapper_.reset();
|
| }
|
|
|
| -bool PpapiDecryptor::CreateSession(uint32 session_id,
|
| - const std::string& content_type,
|
| - const uint8* init_data,
|
| - int init_data_length) {
|
| +void PpapiDecryptor::CreateSession(
|
| + const std::string& init_data_type,
|
| + const uint8* init_data,
|
| + int init_data_length,
|
| + SessionType session_type,
|
| + scoped_ptr<media::MediaKeysSessionPromise> promise) {
|
| DVLOG(2) << __FUNCTION__;
|
| DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
|
|
| - if (!CdmDelegate() ||
|
| - !CdmDelegate()->CreateSession(
|
| - session_id, content_type, init_data, init_data_length)) {
|
| - ReportFailureToCallPlugin(session_id);
|
| - return false;
|
| + if (!CdmDelegate()) {
|
| + promise->reject("InvalidStateError", 0, "CdmDelegate() does not exist.");
|
| + promise.reset();
|
| + return;
|
| }
|
|
|
| - return true;
|
| + CdmDelegate()->CreateSession(init_data_type,
|
| + init_data,
|
| + init_data_length,
|
| + session_type,
|
| + promise.Pass());
|
| }
|
|
|
| -void PpapiDecryptor::LoadSession(uint32 session_id,
|
| - const std::string& web_session_id) {
|
| +void PpapiDecryptor::LoadSession(
|
| + const std::string& web_session_id,
|
| + scoped_ptr<media::MediaKeysSessionPromise> promise) {
|
| DVLOG(2) << __FUNCTION__;
|
| DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
|
|
| if (!CdmDelegate()) {
|
| - ReportFailureToCallPlugin(session_id);
|
| + promise->reject("InvalidStateError", 0, "CdmDelegate() does not exist.");
|
| + promise.reset();
|
| return;
|
| }
|
|
|
| - CdmDelegate()->LoadSession(session_id, web_session_id);
|
| + CdmDelegate()->LoadSession(web_session_id, promise.Pass());
|
| }
|
|
|
| -void PpapiDecryptor::UpdateSession(uint32 session_id,
|
| - const uint8* response,
|
| - int response_length) {
|
| - DVLOG(2) << __FUNCTION__;
|
| +void PpapiDecryptor::UpdateSession(
|
| + const std::string& web_session_id,
|
| + const uint8* response,
|
| + int response_length,
|
| + scoped_ptr<media::MediaKeysSessionPromise> promise) {
|
| DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
|
|
| - if (!CdmDelegate() ||
|
| - !CdmDelegate()->UpdateSession(session_id, response, response_length)) {
|
| - ReportFailureToCallPlugin(session_id);
|
| + if (!CdmDelegate()) {
|
| + promise->reject("InvalidStateError", 0, "CdmDelegate() does not exist.");
|
| + promise.reset();
|
| return;
|
| }
|
| +
|
| + scoped_ptr<SessionUpdatedPromise> update_promise(
|
| + new SessionUpdatedPromise(promise.Pass(),
|
| + base::Bind(&PpapiDecryptor::ResumePlayback,
|
| + weak_ptr_factory_.GetWeakPtr())));
|
| + CdmDelegate()->UpdateSession(
|
| + web_session_id,
|
| + response,
|
| + response_length,
|
| + update_promise.PassAs<media::MediaKeysSessionPromise>());
|
| }
|
|
|
| -void PpapiDecryptor::ReleaseSession(uint32 session_id) {
|
| - DVLOG(2) << __FUNCTION__;
|
| +void PpapiDecryptor::ReleaseSession(
|
| + const std::string& web_session_id,
|
| + scoped_ptr<media::MediaKeysSessionPromise> promise) {
|
| DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
|
|
| - if (!CdmDelegate() || !CdmDelegate()->ReleaseSession(session_id)) {
|
| - ReportFailureToCallPlugin(session_id);
|
| + if (!CdmDelegate()) {
|
| + promise->reject("InvalidStateError", 0, "CdmDelegate() does not exist.");
|
| + promise.reset();
|
| return;
|
| }
|
| +
|
| + CdmDelegate()->ReleaseSession(web_session_id, promise.Pass());
|
| }
|
|
|
| media::Decryptor* PpapiDecryptor::GetDecryptor() {
|
| @@ -330,12 +394,6 @@ void PpapiDecryptor::DeinitializeDecoder(StreamType stream_type) {
|
| CdmDelegate()->DeinitializeDecoder(stream_type);
|
| }
|
|
|
| -void PpapiDecryptor::ReportFailureToCallPlugin(uint32 session_id) {
|
| - DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
| - DVLOG(1) << "Failed to call plugin.";
|
| - session_error_cb_.Run(session_id, kUnknownError, 0);
|
| -}
|
| -
|
| void PpapiDecryptor::OnDecoderInitialized(StreamType stream_type,
|
| bool success) {
|
| DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
| @@ -353,47 +411,43 @@ void PpapiDecryptor::OnDecoderInitialized(StreamType stream_type,
|
| }
|
| }
|
|
|
| -void PpapiDecryptor::OnSessionCreated(uint32 session_id,
|
| - const std::string& web_session_id) {
|
| +void PpapiDecryptor::OnSessionMessage(const std::string& web_session_id,
|
| + const std::vector<uint8>& message,
|
| + const std::string& destination_url) {
|
| DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
| - session_created_cb_.Run(session_id, web_session_id);
|
| + session_message_cb_.Run(web_session_id, message, destination_url);
|
| }
|
|
|
| -void PpapiDecryptor::OnSessionMessage(uint32 session_id,
|
| - const std::vector<uint8>& message,
|
| - const std::string& destination_url) {
|
| +void PpapiDecryptor::OnSessionReady(const std::string& web_session_id) {
|
| DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
| - session_message_cb_.Run(session_id, message, destination_url);
|
| +
|
| + ResumePlayback();
|
| + session_ready_cb_.Run(web_session_id);
|
| }
|
|
|
| -void PpapiDecryptor::OnSessionReady(uint32 session_id) {
|
| +void PpapiDecryptor::OnSessionClosed(const std::string& web_session_id) {
|
| DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
| + session_closed_cb_.Run(web_session_id);
|
| +}
|
|
|
| +void PpapiDecryptor::OnSessionError(const std::string& web_session_id,
|
| + const std::string& error_name,
|
| + uint32 system_code,
|
| + const std::string& error_description) {
|
| + DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
| + session_error_cb_.Run(
|
| + web_session_id, error_name, system_code, error_description);
|
| +}
|
| +
|
| +void PpapiDecryptor::ResumePlayback() {
|
| // Based on the spec, we need to resume playback when update() completes
|
| - // successfully, or when a session is successfully loaded. In both cases,
|
| - // the CDM fires OnSessionReady() event. So we choose to call the NewKeyCBs
|
| - // here.
|
| - // TODO(xhwang): Rename OnSessionReady to indicate that the playback may
|
| - // resume successfully (e.g. a new key is available or available again).
|
| + // successfully, or when a session is successfully loaded (triggered by
|
| + // OnSessionReady()). So we choose to call the NewKeyCBs here.
|
| if (!new_audio_key_cb_.is_null())
|
| new_audio_key_cb_.Run();
|
|
|
| if (!new_video_key_cb_.is_null())
|
| new_video_key_cb_.Run();
|
| -
|
| - session_ready_cb_.Run(session_id);
|
| -}
|
| -
|
| -void PpapiDecryptor::OnSessionClosed(uint32 session_id) {
|
| - DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
| - session_closed_cb_.Run(session_id);
|
| -}
|
| -
|
| -void PpapiDecryptor::OnSessionError(uint32 session_id,
|
| - media::MediaKeys::KeyError error_code,
|
| - uint32 system_code) {
|
| - DCHECK(render_loop_proxy_->BelongsToCurrentThread());
|
| - session_error_cb_.Run(session_id, error_code, system_code);
|
| }
|
|
|
| void PpapiDecryptor::OnFatalPluginError() {
|
|
|