diff options
Diffstat (limited to 'content/renderer/media/crypto')
8 files changed, 185 insertions, 26 deletions
diff --git a/content/renderer/media/crypto/content_decryption_module_factory.cc b/content/renderer/media/crypto/content_decryption_module_factory.cc index e56962f..0730238 100644 --- a/content/renderer/media/crypto/content_decryption_module_factory.cc +++ b/content/renderer/media/crypto/content_decryption_module_factory.cc @@ -30,7 +30,9 @@ scoped_ptr<media::MediaKeys> ContentDecryptionModuleFactory::Create( const media::SessionMessageCB& session_message_cb, const media::SessionReadyCB& session_ready_cb, const media::SessionClosedCB& session_closed_cb, - const media::SessionErrorCB& session_error_cb) { + const media::SessionErrorCB& session_error_cb, + const media::SessionKeysChangeCB& session_keys_change_cb, + const media::SessionExpirationUpdateCB& session_expiration_update_cb) { // TODO(jrummell): Pass |security_origin| to all constructors. // TODO(jrummell): Enable the following line once blink code updated to // check the security origin before calling. @@ -41,8 +43,8 @@ scoped_ptr<media::MediaKeys> ContentDecryptionModuleFactory::Create( #endif if (CanUseAesDecryptor(key_system)) { - return scoped_ptr<media::MediaKeys>( - new media::AesDecryptor(session_message_cb, session_closed_cb)); + return scoped_ptr<media::MediaKeys>(new media::AesDecryptor( + session_message_cb, session_closed_cb, session_keys_change_cb)); } #if defined(ENABLE_PEPPER_CDMS) return scoped_ptr<media::MediaKeys>( @@ -52,7 +54,9 @@ scoped_ptr<media::MediaKeys> ContentDecryptionModuleFactory::Create( session_message_cb, session_ready_cb, session_closed_cb, - session_error_cb)); + session_error_cb, + session_keys_change_cb, + session_expiration_update_cb)); #elif defined(ENABLE_BROWSER_CDMS) scoped_ptr<ProxyMediaKeys> proxy_media_keys = ProxyMediaKeys::Create(key_system, @@ -61,7 +65,9 @@ scoped_ptr<media::MediaKeys> ContentDecryptionModuleFactory::Create( session_message_cb, session_ready_cb, session_closed_cb, - session_error_cb); + session_error_cb, + session_keys_change_cb, + session_expiration_update_cb); if (proxy_media_keys) *cdm_id = proxy_media_keys->GetCdmId(); return proxy_media_keys.PassAs<media::MediaKeys>(); diff --git a/content/renderer/media/crypto/content_decryption_module_factory.h b/content/renderer/media/crypto/content_decryption_module_factory.h index c18bf9d..be91112 100644 --- a/content/renderer/media/crypto/content_decryption_module_factory.h +++ b/content/renderer/media/crypto/content_decryption_module_factory.h @@ -38,7 +38,9 @@ class ContentDecryptionModuleFactory { const media::SessionMessageCB& session_message_cb, const media::SessionReadyCB& session_ready_cb, const media::SessionClosedCB& session_closed_cb, - const media::SessionErrorCB& session_error_cb); + const media::SessionErrorCB& session_error_cb, + const media::SessionKeysChangeCB& session_keys_change_cb, + const media::SessionExpirationUpdateCB& session_expiration_update_cb); }; } // namespace content diff --git a/content/renderer/media/crypto/ppapi_decryptor.cc b/content/renderer/media/crypto/ppapi_decryptor.cc index 8b88362..0a6c14c 100644 --- a/content/renderer/media/crypto/ppapi_decryptor.cc +++ b/content/renderer/media/crypto/ppapi_decryptor.cc @@ -93,7 +93,9 @@ scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create( const media::SessionMessageCB& session_message_cb, const media::SessionReadyCB& session_ready_cb, const media::SessionClosedCB& session_closed_cb, - const media::SessionErrorCB& session_error_cb) { + const media::SessionErrorCB& session_error_cb, + const media::SessionKeysChangeCB& session_keys_change_cb, + const media::SessionExpirationUpdateCB& session_expiration_update_cb) { std::string plugin_type = GetPepperType(key_system); DCHECK(!plugin_type.empty()); scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper = @@ -109,7 +111,9 @@ scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create( session_message_cb, session_ready_cb, session_closed_cb, - session_error_cb)); + session_error_cb, + session_keys_change_cb, + session_expiration_update_cb)); } PpapiDecryptor::PpapiDecryptor( @@ -118,12 +122,16 @@ PpapiDecryptor::PpapiDecryptor( const media::SessionMessageCB& session_message_cb, const media::SessionReadyCB& session_ready_cb, const media::SessionClosedCB& session_closed_cb, - const media::SessionErrorCB& session_error_cb) + const media::SessionErrorCB& session_error_cb, + const media::SessionKeysChangeCB& session_keys_change_cb, + const media::SessionExpirationUpdateCB& session_expiration_update_cb) : pepper_cdm_wrapper_(pepper_cdm_wrapper.Pass()), session_message_cb_(session_message_cb), session_ready_cb_(session_ready_cb), session_closed_cb_(session_closed_cb), session_error_cb_(session_error_cb), + session_keys_change_cb_(session_keys_change_cb), + session_expiration_update_cb_(session_expiration_update_cb), render_loop_proxy_(base::MessageLoopProxy::current()), weak_ptr_factory_(this) { DCHECK(pepper_cdm_wrapper_.get()); @@ -131,6 +139,8 @@ PpapiDecryptor::PpapiDecryptor( DCHECK(!session_ready_cb_.is_null()); DCHECK(!session_closed_cb_.is_null()); DCHECK(!session_error_cb_.is_null()); + DCHECK(!session_keys_change_cb.is_null()); + DCHECK(!session_expiration_update_cb.is_null()); base::WeakPtr<PpapiDecryptor> weak_this = weak_ptr_factory_.GetWeakPtr(); CdmDelegate()->Initialize( @@ -139,6 +149,8 @@ PpapiDecryptor::PpapiDecryptor( base::Bind(&PpapiDecryptor::OnSessionReady, weak_this), base::Bind(&PpapiDecryptor::OnSessionClosed, weak_this), base::Bind(&PpapiDecryptor::OnSessionError, weak_this), + base::Bind(&PpapiDecryptor::OnSessionKeysChange, weak_this), + base::Bind(&PpapiDecryptor::OnSessionExpirationUpdate, weak_this), base::Bind(&PpapiDecryptor::OnFatalPluginError, weak_this)); } @@ -146,6 +158,22 @@ PpapiDecryptor::~PpapiDecryptor() { pepper_cdm_wrapper_.reset(); } +void PpapiDecryptor::SetServerCertificate( + const uint8* certificate_data, + int certificate_data_length, + scoped_ptr<media::SimpleCdmPromise> promise) { + DVLOG(2) << __FUNCTION__; + DCHECK(render_loop_proxy_->BelongsToCurrentThread()); + + if (!CdmDelegate()) { + promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); + return; + } + + CdmDelegate()->SetServerCertificate( + certificate_data, certificate_data_length, promise.Pass()); +} + void PpapiDecryptor::CreateSession( const std::string& init_data_type, const uint8* init_data, @@ -178,6 +206,8 @@ void PpapiDecryptor::LoadSession( return; } + // TODO(jrummell): Intercepting the promise should not be necessary once + // OnSessionKeysChange() is called in all cases. http://crbug.com/413413. scoped_ptr<SessionLoadedPromise> session_loaded_promise( new SessionLoadedPromise(promise.Pass(), base::Bind(&PpapiDecryptor::ResumePlayback, @@ -200,6 +230,8 @@ void PpapiDecryptor::UpdateSession( return; } + // TODO(jrummell): Intercepting the promise should not be necessary once + // OnSessionKeysChange() is called in all cases. http://crbug.com/413413. scoped_ptr<SessionUpdatedPromise> session_updated_promise( new SessionUpdatedPromise(promise.Pass(), base::Bind(&PpapiDecryptor::ResumePlayback, @@ -211,7 +243,19 @@ void PpapiDecryptor::UpdateSession( session_updated_promise.PassAs<media::SimpleCdmPromise>()); } -void PpapiDecryptor::ReleaseSession( +void PpapiDecryptor::CloseSession(const std::string& web_session_id, + scoped_ptr<media::SimpleCdmPromise> promise) { + DCHECK(render_loop_proxy_->BelongsToCurrentThread()); + + if (!CdmDelegate()) { + promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); + return; + } + + CdmDelegate()->CloseSession(web_session_id, promise.Pass()); +} + +void PpapiDecryptor::RemoveSession( const std::string& web_session_id, scoped_ptr<media::SimpleCdmPromise> promise) { DCHECK(render_loop_proxy_->BelongsToCurrentThread()); @@ -221,7 +265,19 @@ void PpapiDecryptor::ReleaseSession( return; } - CdmDelegate()->CloseSession(web_session_id, promise.Pass()); + CdmDelegate()->RemoveSession(web_session_id, promise.Pass()); +} + +void PpapiDecryptor::GetUsableKeyIds(const std::string& web_session_id, + scoped_ptr<media::KeyIdsPromise> promise) { + DCHECK(render_loop_proxy_->BelongsToCurrentThread()); + + if (!CdmDelegate()) { + promise->reject(INVALID_STATE_ERROR, 0, "CdmDelegate() does not exist."); + return; + } + + CdmDelegate()->GetUsableKeyIds(web_session_id, promise.Pass()); } media::Decryptor* PpapiDecryptor::GetDecryptor() { @@ -436,9 +492,30 @@ void PpapiDecryptor::OnSessionMessage(const std::string& web_session_id, session_message_cb_.Run(web_session_id, message, destination_url); } +void PpapiDecryptor::OnSessionKeysChange(const std::string& web_session_id, + bool has_additional_usable_key) { + DCHECK(render_loop_proxy_->BelongsToCurrentThread()); + + // TODO(jrummell): Handling resume playback should be done in the media + // player, not in the Decryptors. http://crbug.com/413413. + if (has_additional_usable_key) + ResumePlayback(); + + session_keys_change_cb_.Run(web_session_id, has_additional_usable_key); +} + +void PpapiDecryptor::OnSessionExpirationUpdate( + const std::string& web_session_id, + const base::Time& new_expiry_time) { + DCHECK(render_loop_proxy_->BelongsToCurrentThread()); + session_expiration_update_cb_.Run(web_session_id, new_expiry_time); +} + void PpapiDecryptor::OnSessionReady(const std::string& web_session_id) { DCHECK(render_loop_proxy_->BelongsToCurrentThread()); + // TODO(jrummell): Calling ResumePlayback() here should not be necessary once + // OnSessionKeysChange() is called in all cases. http://crbug.com/413413. ResumePlayback(); session_ready_cb_.Run(web_session_id); } diff --git a/content/renderer/media/crypto/ppapi_decryptor.h b/content/renderer/media/crypto/ppapi_decryptor.h index c09e4b0..4f215e1 100644 --- a/content/renderer/media/crypto/ppapi_decryptor.h +++ b/content/renderer/media/crypto/ppapi_decryptor.h @@ -38,11 +38,17 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { const media::SessionMessageCB& session_message_cb, const media::SessionReadyCB& session_ready_cb, const media::SessionClosedCB& session_closed_cb, - const media::SessionErrorCB& session_error_cb); + const media::SessionErrorCB& session_error_cb, + const media::SessionKeysChangeCB& session_keys_change_cb, + const media::SessionExpirationUpdateCB& session_expiration_update_cb); virtual ~PpapiDecryptor(); // media::MediaKeys implementation. + virtual void SetServerCertificate( + const uint8* certificate_data, + int certificate_data_length, + scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE; virtual void CreateSession( const std::string& init_data_type, const uint8* init_data, @@ -57,9 +63,15 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { const uint8* response, int response_length, scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE; - virtual void ReleaseSession( + virtual void CloseSession( + const std::string& web_session_id, + scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE; + virtual void RemoveSession( const std::string& web_session_id, scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE; + virtual void GetUsableKeyIds( + const std::string& web_session_id, + scoped_ptr<media::KeyIdsPromise> promise) OVERRIDE; virtual Decryptor* GetDecryptor() OVERRIDE; // media::Decryptor implementation. @@ -83,12 +95,15 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { virtual void DeinitializeDecoder(StreamType stream_type) OVERRIDE; private: - PpapiDecryptor(const std::string& key_system, - scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper, - const media::SessionMessageCB& session_message_cb, - const media::SessionReadyCB& session_ready_cb, - const media::SessionClosedCB& session_closed_cb, - const media::SessionErrorCB& session_error_cb); + PpapiDecryptor( + const std::string& key_system, + scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper, + const media::SessionMessageCB& session_message_cb, + const media::SessionReadyCB& session_ready_cb, + const media::SessionClosedCB& session_closed_cb, + const media::SessionErrorCB& session_error_cb, + const media::SessionKeysChangeCB& session_keys_change_cb, + const media::SessionExpirationUpdateCB& session_expiration_update_cb); void OnDecoderInitialized(StreamType stream_type, bool success); @@ -96,6 +111,10 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { void OnSessionMessage(const std::string& web_session_id, const std::vector<uint8>& message, const GURL& destination_url); + void OnSessionKeysChange(const std::string& web_session_id, + bool has_additional_usable_key); + void OnSessionExpirationUpdate(const std::string& web_session_id, + const base::Time& new_expiry_time); void OnSessionReady(const std::string& web_session_id); void OnSessionClosed(const std::string& web_session_id); void OnSessionError(const std::string& web_session_id, @@ -122,6 +141,8 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { media::SessionReadyCB session_ready_cb_; media::SessionClosedCB session_closed_cb_; media::SessionErrorCB session_error_cb_; + media::SessionKeysChangeCB session_keys_change_cb_; + media::SessionExpirationUpdateCB session_expiration_update_cb_; scoped_refptr<base::MessageLoopProxy> render_loop_proxy_; diff --git a/content/renderer/media/crypto/proxy_decryptor.cc b/content/renderer/media/crypto/proxy_decryptor.cc index 8a9a757..98c301c 100644 --- a/content/renderer/media/crypto/proxy_decryptor.cc +++ b/content/renderer/media/crypto/proxy_decryptor.cc @@ -218,7 +218,7 @@ void ProxyDecryptor::CancelKeyRequest(const std::string& web_session_id) { base::Bind(&ProxyDecryptor::OnSessionError, weak_ptr_factory_.GetWeakPtr(), web_session_id))); - media_keys_->ReleaseSession(web_session_id, promise.Pass()); + media_keys_->RemoveSession(web_session_id, promise.Pass()); } scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys( @@ -240,6 +240,10 @@ scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys( base::Bind(&ProxyDecryptor::OnSessionClosed, weak_ptr_factory_.GetWeakPtr()), base::Bind(&ProxyDecryptor::OnSessionError, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&ProxyDecryptor::OnSessionKeysChange, + weak_ptr_factory_.GetWeakPtr()), + base::Bind(&ProxyDecryptor::OnSessionExpirationUpdate, weak_ptr_factory_.GetWeakPtr())); } @@ -261,6 +265,17 @@ void ProxyDecryptor::OnSessionMessage(const std::string& web_session_id, key_message_cb_.Run(web_session_id, message, destination_url); } +void ProxyDecryptor::OnSessionKeysChange(const std::string& web_session_id, + bool has_additional_usable_key) { + // EME v0.1b doesn't support this event. +} + +void ProxyDecryptor::OnSessionExpirationUpdate( + const std::string& web_session_id, + const base::Time& new_expiry_time) { + // EME v0.1b doesn't support this event. +} + void ProxyDecryptor::OnSessionReady(const std::string& web_session_id) { key_added_cb_.Run(web_session_id); } diff --git a/content/renderer/media/crypto/proxy_decryptor.h b/content/renderer/media/crypto/proxy_decryptor.h index b1e736d..0a6c298 100644 --- a/content/renderer/media/crypto/proxy_decryptor.h +++ b/content/renderer/media/crypto/proxy_decryptor.h @@ -89,6 +89,10 @@ class ProxyDecryptor { void OnSessionMessage(const std::string& web_session_id, const std::vector<uint8>& message, const GURL& default_url); + void OnSessionKeysChange(const std::string& web_session_id, + bool has_additional_usable_key); + void OnSessionExpirationUpdate(const std::string& web_session_id, + const base::Time& new_expiry_time); void OnSessionReady(const std::string& web_session_id); void OnSessionClosed(const std::string& web_session_id); void OnSessionError(const std::string& web_session_id, diff --git a/content/renderer/media/crypto/proxy_media_keys.cc b/content/renderer/media/crypto/proxy_media_keys.cc index 17e918d..267a0d1 100644 --- a/content/renderer/media/crypto/proxy_media_keys.cc +++ b/content/renderer/media/crypto/proxy_media_keys.cc @@ -22,8 +22,13 @@ scoped_ptr<ProxyMediaKeys> ProxyMediaKeys::Create( const media::SessionMessageCB& session_message_cb, const media::SessionReadyCB& session_ready_cb, const media::SessionClosedCB& session_closed_cb, - const media::SessionErrorCB& session_error_cb) { + const media::SessionErrorCB& session_error_cb, + const media::SessionKeysChangeCB& session_keys_change_cb, + const media::SessionExpirationUpdateCB& session_expiration_update_cb) { DCHECK(manager); + + // TODO(jrummell): Add support for SessionKeysChangeCB and + // SessionExpirationUpdateCB. scoped_ptr<ProxyMediaKeys> proxy_media_keys( new ProxyMediaKeys(manager, session_message_cb, @@ -48,6 +53,13 @@ ProxyMediaKeys::~ProxyMediaKeys() { session_id_to_promise_map_.clear(); } +void ProxyMediaKeys::SetServerCertificate( + const uint8* certificate_data, + int certificate_data_length, + scoped_ptr<media::SimpleCdmPromise> promise) { + promise->reject(NOT_SUPPORTED_ERROR, 0, "Not yet implemented."); +} + void ProxyMediaKeys::CreateSession( const std::string& init_data_type, const uint8* init_data, @@ -107,9 +119,8 @@ void ProxyMediaKeys::UpdateSession( std::vector<uint8>(response, response + response_length)); } -void ProxyMediaKeys::ReleaseSession( - const std::string& web_session_id, - scoped_ptr<media::SimpleCdmPromise> promise) { +void ProxyMediaKeys::CloseSession(const std::string& web_session_id, + scoped_ptr<media::SimpleCdmPromise> promise) { uint32 session_id = LookupSessionId(web_session_id); if (!session_id) { promise->reject(INVALID_ACCESS_ERROR, 0, "Session does not exist."); @@ -120,6 +131,17 @@ void ProxyMediaKeys::ReleaseSession( manager_->ReleaseSession(cdm_id_, session_id); } +void ProxyMediaKeys::RemoveSession( + const std::string& web_session_id, + scoped_ptr<media::SimpleCdmPromise> promise) { + promise->reject(NOT_SUPPORTED_ERROR, 0, "Not yet implemented."); +} + +void ProxyMediaKeys::GetUsableKeyIds(const std::string& web_session_id, + scoped_ptr<media::KeyIdsPromise> promise) { + promise->reject(NOT_SUPPORTED_ERROR, 0, "Not yet implemented."); +} + void ProxyMediaKeys::OnSessionCreated(uint32 session_id, const std::string& web_session_id) { AssignWebSessionId(session_id, web_session_id); diff --git a/content/renderer/media/crypto/proxy_media_keys.h b/content/renderer/media/crypto/proxy_media_keys.h index 4ebd4c1..c0c790e 100644 --- a/content/renderer/media/crypto/proxy_media_keys.h +++ b/content/renderer/media/crypto/proxy_media_keys.h @@ -30,11 +30,17 @@ class ProxyMediaKeys : public media::MediaKeys { const media::SessionMessageCB& session_message_cb, const media::SessionReadyCB& session_ready_cb, const media::SessionClosedCB& session_closed_cb, - const media::SessionErrorCB& session_error_cb); + const media::SessionErrorCB& session_error_cb, + const media::SessionKeysChangeCB& session_keys_change_cb, + const media::SessionExpirationUpdateCB& session_expiration_update_cb); virtual ~ProxyMediaKeys(); // MediaKeys implementation. + virtual void SetServerCertificate( + const uint8* certificate_data, + int certificate_data_length, + scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE; virtual void CreateSession( const std::string& init_data_type, const uint8* init_data, @@ -49,9 +55,15 @@ class ProxyMediaKeys : public media::MediaKeys { const uint8* response, int response_length, scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE; - virtual void ReleaseSession( + virtual void CloseSession( + const std::string& web_session_id, + scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE; + virtual void RemoveSession( const std::string& web_session_id, scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE; + virtual void GetUsableKeyIds( + const std::string& web_session_id, + scoped_ptr<media::KeyIdsPromise> promise) OVERRIDE; // Callbacks. void OnSessionCreated(uint32 session_id, const std::string& web_session_id); |