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..dc820ba695be49a97a0a879bc51efc331332a10b 100644 |
--- a/content/renderer/media/crypto/ppapi_decryptor.cc |
+++ b/content/renderer/media/crypto/ppapi_decryptor.cc |
@@ -16,6 +16,7 @@ |
#include "content/renderer/pepper/content_decryptor_delegate.h" |
#include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
#include "media/base/audio_decoder_config.h" |
+#include "media/base/cdm_promise.h" |
#include "media/base/data_buffer.h" |
#include "media/base/decoder_buffer.h" |
#include "media/base/video_decoder_config.h" |
@@ -23,11 +24,30 @@ |
namespace content { |
+// This class is need so that resolving an Update() promise triggers playback |
xhwang
2014/05/23 06:01:23
s/need/needed
jrummell
2014/05/29 00:54:40
Done.
|
+// of the stream. |
+class SessionUpdatedPromise : public media::SimpleCdmPromise { |
+ public: |
+ SessionUpdatedPromise(scoped_ptr<media::SimpleCdmPromise> caller_promise, |
+ base::Callback<void()> resolve_cb) |
xhwang
2014/05/23 06:01:23
s/resolve/additional_resolve/ ? It's not super cle
jrummell
2014/05/29 00:54:40
Done.
|
+ : CdmPromise(resolve_cb, |
+ base::Bind(&media::SimpleCdmPromise::reject, |
+ base::Unretained(caller_promise.get()))), |
+ caller_promise_(caller_promise.Pass()) {} |
+ |
+ virtual void resolve() OVERRIDE { |
+ media::SimpleCdmPromise::resolve(); |
+ caller_promise_->resolve(); |
+ } |
+ |
+ protected: |
+ scoped_ptr<media::SimpleCdmPromise> caller_promise_; |
xhwang
2014/05/23 06:01:23
We use both composition and inheritance? This seem
jrummell
2014/05/29 00:54:40
Done.
|
+}; |
+ |
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 +64,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 +73,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 +85,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 +93,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 +104,83 @@ 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::NewSessionCdmPromise> 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( |
+ EXCEPTION_INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); |
+ promise.reset(); |
xhwang
2014/05/23 06:01:23
Here and elsewhere: promise is a scoped_ptr; you d
jrummell
2014/05/29 00:54:40
Done to make it obvious. Removed since the promise
|
+ 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::NewSessionCdmPromise> promise) { |
DVLOG(2) << __FUNCTION__; |
DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
if (!CdmDelegate()) { |
- ReportFailureToCallPlugin(session_id); |
+ promise->reject( |
+ EXCEPTION_INVALID_STATE_ERROR, 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::SimpleCdmPromise> promise) { |
DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
- if (!CdmDelegate() || |
- !CdmDelegate()->UpdateSession(session_id, response, response_length)) { |
- ReportFailureToCallPlugin(session_id); |
+ if (!CdmDelegate()) { |
+ promise->reject( |
+ EXCEPTION_INVALID_STATE_ERROR, 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::SimpleCdmPromise>()); |
} |
-void PpapiDecryptor::ReleaseSession(uint32 session_id) { |
- DVLOG(2) << __FUNCTION__; |
+void PpapiDecryptor::ReleaseSession( |
+ const std::string& web_session_id, |
+ scoped_ptr<media::SimpleCdmPromise> promise) { |
DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
- if (!CdmDelegate() || !CdmDelegate()->ReleaseSession(session_id)) { |
- ReportFailureToCallPlugin(session_id); |
+ if (!CdmDelegate()) { |
+ promise->reject( |
+ EXCEPTION_INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); |
+ promise.reset(); |
return; |
} |
+ |
+ CdmDelegate()->ReleaseSession(web_session_id, promise.Pass()); |
} |
media::Decryptor* PpapiDecryptor::GetDecryptor() { |
@@ -330,12 +371,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 +388,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()); |
+ |
+ ResumePlayback(); |
+ session_ready_cb_.Run(web_session_id); |
+} |
+ |
+void PpapiDecryptor::OnSessionClosed(const std::string& web_session_id) { |
DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
- session_message_cb_.Run(session_id, message, destination_url); |
+ session_closed_cb_.Run(web_session_id); |
} |
-void PpapiDecryptor::OnSessionReady(uint32 session_id) { |
+void PpapiDecryptor::OnSessionError(const std::string& web_session_id, |
+ MediaKeys::Exception exception_code, |
+ uint32 system_code, |
+ const std::string& error_description) { |
DCHECK(render_loop_proxy_->BelongsToCurrentThread()); |
+ session_error_cb_.Run( |
+ web_session_id, exception_code, 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() { |