diff options
author | jrummell <jrummell@chromium.org> | 2015-05-05 15:27:18 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-05 22:28:05 +0000 |
commit | 87a2db5daf3fbada56114caa4bb61e596ad459a2 (patch) | |
tree | fad907e44626d8cb3bd9938d16da66995e29f16a /content | |
parent | f7b39b78d4e052cd57fe9a277e578c4078c7ce5f (diff) | |
download | chromium_src-87a2db5daf3fbada56114caa4bb61e596ad459a2.zip chromium_src-87a2db5daf3fbada56114caa4bb61e596ad459a2.tar.gz chromium_src-87a2db5daf3fbada56114caa4bb61e596ad459a2.tar.bz2 |
Initialize the CDM asynchronously
Currently initialization happens asynchronously, but as Initialize()
has no way to report success/failure, subsequent calls need to check
that it succeeded. This change passes a promise to Initialize() so
that the CDM can report success/failure properly.
BUG=407435,469003
TEST=EME tests pass
Review URL: https://codereview.chromium.org/1102363005
Cr-Commit-Position: refs/heads/master@{#328418}
Diffstat (limited to 'content')
-rw-r--r-- | content/content_renderer.gypi | 2 | ||||
-rw-r--r-- | content/renderer/media/crypto/cdm_initialized_promise.cc | 30 | ||||
-rw-r--r-- | content/renderer/media/crypto/cdm_initialized_promise.h | 39 | ||||
-rw-r--r-- | content/renderer/media/crypto/ppapi_decryptor.cc | 46 | ||||
-rw-r--r-- | content/renderer/media/crypto/ppapi_decryptor.h | 14 | ||||
-rw-r--r-- | content/renderer/media/crypto/proxy_media_keys.cc | 24 | ||||
-rw-r--r-- | content/renderer/media/crypto/proxy_media_keys.h | 9 | ||||
-rw-r--r-- | content/renderer/media/crypto/render_cdm_factory.cc | 49 | ||||
-rw-r--r-- | content/renderer/media/crypto/render_cdm_factory.h | 2 | ||||
-rw-r--r-- | content/renderer/pepper/content_decryptor_delegate.cc | 6 | ||||
-rw-r--r-- | content/renderer/pepper/content_decryptor_delegate.h | 3 |
11 files changed, 168 insertions, 56 deletions
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index b4afefe..2f65b7a 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -262,6 +262,8 @@ 'renderer/media/audio_message_filter.h', 'renderer/media/audio_renderer_mixer_manager.cc', 'renderer/media/audio_renderer_mixer_manager.h', + 'renderer/media/crypto/cdm_initialized_promise.cc', + 'renderer/media/crypto/cdm_initialized_promise.h', 'renderer/media/crypto/pepper_cdm_wrapper.h', 'renderer/media/crypto/pepper_cdm_wrapper_impl.cc', 'renderer/media/crypto/pepper_cdm_wrapper_impl.h', diff --git a/content/renderer/media/crypto/cdm_initialized_promise.cc b/content/renderer/media/crypto/cdm_initialized_promise.cc new file mode 100644 index 0000000..5a72c6d --- /dev/null +++ b/content/renderer/media/crypto/cdm_initialized_promise.cc @@ -0,0 +1,30 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/crypto/cdm_initialized_promise.h" + +namespace content { + +CdmInitializedPromise::CdmInitializedPromise( + const media::CdmCreatedCB& cdm_created_cb, + scoped_ptr<media::MediaKeys> cdm) + : cdm_created_cb_(cdm_created_cb), cdm_(cdm.Pass()) { +} + +CdmInitializedPromise::~CdmInitializedPromise() { +} + +void CdmInitializedPromise::resolve() { + MarkPromiseSettled(); + cdm_created_cb_.Run(cdm_.Pass()); +} + +void CdmInitializedPromise::reject(media::MediaKeys::Exception exception_code, + uint32 system_code, + const std::string& error_message) { + MarkPromiseSettled(); + cdm_created_cb_.Run(nullptr); +} + +} // namespace content diff --git a/content/renderer/media/crypto/cdm_initialized_promise.h b/content/renderer/media/crypto/cdm_initialized_promise.h new file mode 100644 index 0000000..7c3d4c3 --- /dev/null +++ b/content/renderer/media/crypto/cdm_initialized_promise.h @@ -0,0 +1,39 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_MEDIA_CRYPTO_CDM_INITIALIZED_PROMISE_H_ +#define CONTENT_RENDERER_MEDIA_CRYPTO_CDM_INITIALIZED_PROMISE_H_ + +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "media/base/cdm_factory.h" +#include "media/base/cdm_promise.h" +#include "media/base/media_keys.h" + +namespace content { + +// Promise to be resolved when the CDM is initialized. It owns the MediaKeys +// object until the initialization completes, which it then passes to +// |cdm_created_cb|. +class CdmInitializedPromise : public media::SimpleCdmPromise { + public: + CdmInitializedPromise(const media::CdmCreatedCB& cdm_created_cb, + scoped_ptr<media::MediaKeys> cdm); + ~CdmInitializedPromise() override; + + // SimpleCdmPromise implementation. + void resolve() override; + void reject(media::MediaKeys::Exception exception_code, + uint32 system_code, + const std::string& error_message) override; + + private: + media::CdmCreatedCB cdm_created_cb_; + scoped_ptr<media::MediaKeys> cdm_; +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_CRYPTO_CDM_INITIALIZED_PROMISE_H_ diff --git a/content/renderer/media/crypto/ppapi_decryptor.cc b/content/renderer/media/crypto/ppapi_decryptor.cc index d50e911..8fa799f 100644 --- a/content/renderer/media/crypto/ppapi_decryptor.cc +++ b/content/renderer/media/crypto/ppapi_decryptor.cc @@ -10,6 +10,7 @@ #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop_proxy.h" +#include "content/renderer/media/crypto/cdm_initialized_promise.h" #include "content/renderer/pepper/content_decryptor_delegate.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "media/base/audio_decoder_config.h" @@ -22,7 +23,7 @@ namespace content { -scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create( +void PpapiDecryptor::Create( const std::string& key_system, bool allow_distinctive_identifier, bool allow_persistent_state, @@ -32,27 +33,33 @@ scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create( const media::SessionClosedCB& session_closed_cb, const media::LegacySessionErrorCB& legacy_session_error_cb, const media::SessionKeysChangeCB& session_keys_change_cb, - const media::SessionExpirationUpdateCB& session_expiration_update_cb) { + const media::SessionExpirationUpdateCB& session_expiration_update_cb, + const media::CdmCreatedCB& cdm_created_cb) { std::string plugin_type = media::GetPepperType(key_system); DCHECK(!plugin_type.empty()); scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper = create_pepper_cdm_cb.Run(plugin_type, security_origin); if (!pepper_cdm_wrapper) { DLOG(ERROR) << "Plugin instance creation failed."; - return scoped_ptr<PpapiDecryptor>(); + base::MessageLoopProxy::current()->PostTask( + FROM_HERE, base::Bind(cdm_created_cb, nullptr)); } - return scoped_ptr<PpapiDecryptor>(new PpapiDecryptor( - key_system, allow_distinctive_identifier, allow_persistent_state, - pepper_cdm_wrapper.Pass(), session_message_cb, session_closed_cb, - legacy_session_error_cb, session_keys_change_cb, - session_expiration_update_cb)); + scoped_ptr<PpapiDecryptor> ppapi_decryptor( + new PpapiDecryptor(pepper_cdm_wrapper.Pass(), session_message_cb, + session_closed_cb, legacy_session_error_cb, + session_keys_change_cb, session_expiration_update_cb)); + + // PpapiDecryptor ownership passed to the promise, but keep a copy in order + // to call InitializeCdm(). + PpapiDecryptor* ppapi_decryptor_copy = ppapi_decryptor.get(); + scoped_ptr<CdmInitializedPromise> promise( + new CdmInitializedPromise(cdm_created_cb, ppapi_decryptor.Pass())); + ppapi_decryptor_copy->InitializeCdm(key_system, allow_distinctive_identifier, + allow_persistent_state, promise.Pass()); } PpapiDecryptor::PpapiDecryptor( - const std::string& key_system, - bool allow_distinctive_identifier, - bool allow_persistent_state, scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper, const media::SessionMessageCB& session_message_cb, const media::SessionClosedCB& session_closed_cb, @@ -73,7 +80,17 @@ PpapiDecryptor::PpapiDecryptor( DCHECK(!legacy_session_error_cb_.is_null()); DCHECK(!session_keys_change_cb.is_null()); DCHECK(!session_expiration_update_cb.is_null()); +} + +PpapiDecryptor::~PpapiDecryptor() { + pepper_cdm_wrapper_.reset(); +} +void PpapiDecryptor::InitializeCdm( + const std::string& key_system, + bool allow_distinctive_identifier, + bool allow_persistent_state, + scoped_ptr<media::SimpleCdmPromise> promise) { base::WeakPtr<PpapiDecryptor> weak_this = weak_ptr_factory_.GetWeakPtr(); CdmDelegate()->Initialize( key_system, allow_distinctive_identifier, allow_persistent_state, @@ -82,11 +99,8 @@ PpapiDecryptor::PpapiDecryptor( base::Bind(&PpapiDecryptor::OnLegacySessionError, weak_this), base::Bind(&PpapiDecryptor::OnSessionKeysChange, weak_this), base::Bind(&PpapiDecryptor::OnSessionExpirationUpdate, weak_this), - base::Bind(&PpapiDecryptor::OnFatalPluginError, weak_this)); -} - -PpapiDecryptor::~PpapiDecryptor() { - pepper_cdm_wrapper_.reset(); + base::Bind(&PpapiDecryptor::OnFatalPluginError, weak_this), + promise.Pass()); } void PpapiDecryptor::SetServerCertificate( diff --git a/content/renderer/media/crypto/ppapi_decryptor.h b/content/renderer/media/crypto/ppapi_decryptor.h index 374b5c1..c818fc8 100644 --- a/content/renderer/media/crypto/ppapi_decryptor.h +++ b/content/renderer/media/crypto/ppapi_decryptor.h @@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "content/renderer/media/crypto/pepper_cdm_wrapper.h" #include "media/base/cdm_context.h" +#include "media/base/cdm_factory.h" #include "media/base/decryptor.h" #include "media/base/media_keys.h" #include "media/base/video_decoder_config.h" @@ -34,7 +35,7 @@ class PpapiDecryptor : public media::MediaKeys, public media::CdmContext, public media::Decryptor { public: - static scoped_ptr<PpapiDecryptor> Create( + static void Create( const std::string& key_system, bool allow_distinctive_identifier, bool allow_persistent_state, @@ -44,7 +45,8 @@ class PpapiDecryptor : public media::MediaKeys, const media::SessionClosedCB& session_closed_cb, const media::LegacySessionErrorCB& legacy_session_error_cb, const media::SessionKeysChangeCB& session_keys_change_cb, - const media::SessionExpirationUpdateCB& session_expiration_update_cb); + const media::SessionExpirationUpdateCB& session_expiration_update_cb, + const media::CdmCreatedCB& cdm_created_cb); ~PpapiDecryptor() override; @@ -95,9 +97,6 @@ class PpapiDecryptor : public media::MediaKeys, private: PpapiDecryptor( - const std::string& key_system, - bool allow_distinctive_identifier, - bool allow_persistent_state, scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper, const media::SessionMessageCB& session_message_cb, const media::SessionClosedCB& session_closed_cb, @@ -105,6 +104,11 @@ class PpapiDecryptor : public media::MediaKeys, const media::SessionKeysChangeCB& session_keys_change_cb, const media::SessionExpirationUpdateCB& session_expiration_update_cb); + void InitializeCdm(const std::string& key_system, + bool allow_distinctive_identifier, + bool allow_persistent_state, + scoped_ptr<media::SimpleCdmPromise> promise); + void OnDecoderInitialized(StreamType stream_type, bool success); // Callbacks for |plugin_cdm_delegate_| to fire session events. diff --git a/content/renderer/media/crypto/proxy_media_keys.cc b/content/renderer/media/crypto/proxy_media_keys.cc index 9f121fe..119a64f 100644 --- a/content/renderer/media/crypto/proxy_media_keys.cc +++ b/content/renderer/media/crypto/proxy_media_keys.cc @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "base/logging.h" #include "base/stl_util.h" +#include "content/renderer/media/crypto/cdm_initialized_promise.h" #include "content/renderer/media/crypto/renderer_cdm_manager.h" #include "media/base/cdm_key_information.h" #include "media/base/cdm_promise.h" @@ -16,7 +17,7 @@ namespace content { -scoped_ptr<ProxyMediaKeys> ProxyMediaKeys::Create( +void ProxyMediaKeys::Create( const std::string& key_system, const GURL& security_origin, RendererCdmManager* manager, @@ -24,13 +25,20 @@ scoped_ptr<ProxyMediaKeys> ProxyMediaKeys::Create( const media::SessionClosedCB& session_closed_cb, const media::LegacySessionErrorCB& legacy_session_error_cb, const media::SessionKeysChangeCB& session_keys_change_cb, - const media::SessionExpirationUpdateCB& session_expiration_update_cb) { + const media::SessionExpirationUpdateCB& session_expiration_update_cb, + const media::CdmCreatedCB& cdm_created_cb) { DCHECK(manager); scoped_ptr<ProxyMediaKeys> proxy_media_keys(new ProxyMediaKeys( manager, session_message_cb, session_closed_cb, legacy_session_error_cb, session_keys_change_cb, session_expiration_update_cb)); - proxy_media_keys->InitializeCdm(key_system, security_origin); - return proxy_media_keys.Pass(); + + // ProxyMediaKeys ownership passed to the promise, but keep a copy in order + // to call InitializeCdm(). + ProxyMediaKeys* proxy_media_keys_copy = proxy_media_keys.get(); + scoped_ptr<CdmInitializedPromise> promise( + new CdmInitializedPromise(cdm_created_cb, proxy_media_keys.Pass())); + proxy_media_keys_copy->InitializeCdm(key_system, security_origin, + promise.Pass()); } ProxyMediaKeys::~ProxyMediaKeys() { @@ -193,9 +201,13 @@ ProxyMediaKeys::ProxyMediaKeys( cdm_id_ = manager->RegisterMediaKeys(this); } -void ProxyMediaKeys::InitializeCdm(const std::string& key_system, - const GURL& security_origin) { +void ProxyMediaKeys::InitializeCdm( + const std::string& key_system, + const GURL& security_origin, + scoped_ptr<media::SimpleCdmPromise> promise) { + // TODO(jrummell): |Pass promise| on. http://crbug.com/469003. manager_->InitializeCdm(cdm_id_, this, key_system, security_origin); + promise->resolve(); } } // namespace content diff --git a/content/renderer/media/crypto/proxy_media_keys.h b/content/renderer/media/crypto/proxy_media_keys.h index 979de0a..ac3ec03 100644 --- a/content/renderer/media/crypto/proxy_media_keys.h +++ b/content/renderer/media/crypto/proxy_media_keys.h @@ -13,6 +13,7 @@ #include "base/containers/hash_tables.h" #include "base/containers/scoped_ptr_hash_map.h" #include "media/base/cdm_context.h" +#include "media/base/cdm_factory.h" #include "media/base/cdm_promise.h" #include "media/base/cdm_promise_adapter.h" #include "media/base/media_keys.h" @@ -26,7 +27,7 @@ class RendererCdmManager; // A MediaKeys proxy that wraps the EME part of RendererCdmManager. class ProxyMediaKeys : public media::MediaKeys, public media::CdmContext { public: - static scoped_ptr<ProxyMediaKeys> Create( + static void Create( const std::string& key_system, const GURL& security_origin, RendererCdmManager* manager, @@ -34,7 +35,8 @@ class ProxyMediaKeys : public media::MediaKeys, public media::CdmContext { const media::SessionClosedCB& session_closed_cb, const media::LegacySessionErrorCB& legacy_session_error_cb, const media::SessionKeysChangeCB& session_keys_change_cb, - const media::SessionExpirationUpdateCB& session_expiration_update_cb); + const media::SessionExpirationUpdateCB& session_expiration_update_cb, + const media::CdmCreatedCB& cdm_created_cb); ~ProxyMediaKeys() override; @@ -97,7 +99,8 @@ class ProxyMediaKeys : public media::MediaKeys, public media::CdmContext { const media::SessionExpirationUpdateCB& session_expiration_update_cb); void InitializeCdm(const std::string& key_system, - const GURL& security_origin); + const GURL& security_origin, + scoped_ptr<media::SimpleCdmPromise> promise); RendererCdmManager* manager_; int cdm_id_; diff --git a/content/renderer/media/crypto/render_cdm_factory.cc b/content/renderer/media/crypto/render_cdm_factory.cc index e551226f..6e81163 100644 --- a/content/renderer/media/crypto/render_cdm_factory.cc +++ b/content/renderer/media/crypto/render_cdm_factory.cc @@ -7,8 +7,11 @@ #include "base/bind.h" #include "base/location.h" #include "base/logging.h" +#include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop_proxy.h" +#include "media/base/cdm_promise.h" #include "media/base/key_systems.h" +#include "media/base/media_keys.h" #include "media/cdm/aes_decryptor.h" #include "url/gurl.h" #if defined(ENABLE_PEPPER_CDMS) @@ -49,7 +52,7 @@ void RenderCdmFactory::Create( const media::LegacySessionErrorCB& legacy_session_error_cb, const media::SessionKeysChangeCB& session_keys_change_cb, const media::SessionExpirationUpdateCB& session_expiration_update_cb, - const CdmCreatedCB& cdm_created_cb) { + const media::CdmCreatedCB& cdm_created_cb) { DCHECK(thread_checker_.CalledOnValidThread()); if (!security_origin.is_valid()) { @@ -58,35 +61,37 @@ void RenderCdmFactory::Create( return; } - scoped_ptr<media::MediaKeys> cdm; - if (media::CanUseAesDecryptor(key_system)) { // TODO(sandersd): Currently the prefixed API always allows distinctive // identifiers and persistent state. Once that changes we can sanity check // here that neither is allowed for AesDecryptor, since it does not support // them and should never be configured that way. http://crbug.com/455271 - cdm.reset(new media::AesDecryptor(security_origin, session_message_cb, - session_closed_cb, - session_keys_change_cb)); - } else { -#if defined(ENABLE_PEPPER_CDMS) - cdm = PpapiDecryptor::Create( - key_system, allow_distinctive_identifier, allow_persistent_state, - security_origin, create_pepper_cdm_cb_, session_message_cb, - session_closed_cb, legacy_session_error_cb, session_keys_change_cb, - session_expiration_update_cb); -#elif defined(ENABLE_BROWSER_CDMS) - DCHECK(allow_distinctive_identifier); - DCHECK(allow_persistent_state); - cdm = ProxyMediaKeys::Create( - key_system, security_origin, manager_, session_message_cb, - session_closed_cb, legacy_session_error_cb, session_keys_change_cb, - session_expiration_update_cb); -#endif // defined(ENABLE_PEPPER_CDMS) + scoped_ptr<media::MediaKeys> cdm( + new media::AesDecryptor(security_origin, session_message_cb, + session_closed_cb, session_keys_change_cb)); + base::MessageLoopProxy::current()->PostTask( + FROM_HERE, base::Bind(cdm_created_cb, base::Passed(&cdm))); + return; } +#if defined(ENABLE_PEPPER_CDMS) + PpapiDecryptor::Create( + key_system, allow_distinctive_identifier, allow_persistent_state, + security_origin, create_pepper_cdm_cb_, session_message_cb, + session_closed_cb, legacy_session_error_cb, session_keys_change_cb, + session_expiration_update_cb, cdm_created_cb); +#elif defined(ENABLE_BROWSER_CDMS) + DCHECK(allow_distinctive_identifier); + DCHECK(allow_persistent_state); + ProxyMediaKeys::Create(key_system, security_origin, manager_, + session_message_cb, session_closed_cb, + legacy_session_error_cb, session_keys_change_cb, + session_expiration_update_cb, cdm_created_cb); +#else + // No possible CDM to create, so fail the request. base::MessageLoopProxy::current()->PostTask( - FROM_HERE, base::Bind(cdm_created_cb, base::Passed(&cdm))); + FROM_HERE, base::Bind(cdm_created_cb, nullptr)); +#endif // defined(ENABLE_PEPPER_CDMS) } } // namespace content diff --git a/content/renderer/media/crypto/render_cdm_factory.h b/content/renderer/media/crypto/render_cdm_factory.h index af2d7ad..1be9dcf 100644 --- a/content/renderer/media/crypto/render_cdm_factory.h +++ b/content/renderer/media/crypto/render_cdm_factory.h @@ -50,7 +50,7 @@ class RenderCdmFactory : public media::CdmFactory, public RenderFrameObserver { const media::LegacySessionErrorCB& legacy_session_error_cb, const media::SessionKeysChangeCB& session_keys_change_cb, const media::SessionExpirationUpdateCB& session_expiration_update_cb, - const CdmCreatedCB& cdm_created_cb) override; + const media::CdmCreatedCB& cdm_created_cb) override; private: #if defined(ENABLE_PEPPER_CDMS) diff --git a/content/renderer/pepper/content_decryptor_delegate.cc b/content/renderer/pepper/content_decryptor_delegate.cc index 0cf812d..82f9894 100644 --- a/content/renderer/pepper/content_decryptor_delegate.cc +++ b/content/renderer/pepper/content_decryptor_delegate.cc @@ -382,7 +382,8 @@ void ContentDecryptorDelegate::Initialize( const media::LegacySessionErrorCB& legacy_session_error_cb, const media::SessionKeysChangeCB& session_keys_change_cb, const media::SessionExpirationUpdateCB& session_expiration_update_cb, - const base::Closure& fatal_plugin_error_cb) { + const base::Closure& fatal_plugin_error_cb, + scoped_ptr<media::SimpleCdmPromise> promise) { DCHECK(!key_system.empty()); DCHECK(key_system_.empty()); key_system_ = key_system; @@ -394,8 +395,9 @@ void ContentDecryptorDelegate::Initialize( session_expiration_update_cb_ = session_expiration_update_cb; fatal_plugin_error_cb_ = fatal_plugin_error_cb; + uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); plugin_decryption_interface_->Initialize( - pp_instance_, StringVar::StringToPPVar(key_system_), + pp_instance_, promise_id, StringVar::StringToPPVar(key_system_), PP_FromBool(allow_distinctive_identifier), PP_FromBool(allow_persistent_state)); } diff --git a/content/renderer/pepper/content_decryptor_delegate.h b/content/renderer/pepper/content_decryptor_delegate.h index cb3791d..09b0917 100644 --- a/content/renderer/pepper/content_decryptor_delegate.h +++ b/content/renderer/pepper/content_decryptor_delegate.h @@ -56,7 +56,8 @@ class ContentDecryptorDelegate { const media::LegacySessionErrorCB& legacy_session_error_cb, const media::SessionKeysChangeCB& session_keys_change_cb, const media::SessionExpirationUpdateCB& session_expiration_update_cb, - const base::Closure& fatal_plugin_error_cb); + const base::Closure& fatal_plugin_error_cb, + scoped_ptr<media::SimpleCdmPromise> promise); void InstanceCrashed(); |