diff options
author | jrummell@chromium.org <jrummell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-27 19:40:27 +0000 |
---|---|---|
committer | jrummell@chromium.org <jrummell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-27 19:40:27 +0000 |
commit | bf54920ec8cdd09ca4619a0689fc5d5713a99287 (patch) | |
tree | 803573dc6ef5481fe9023cac830ee9caed92a532 | |
parent | 3aa9ca7d36a77ac1cf4077ed041b0c624dea8eb2 (diff) | |
download | chromium_src-bf54920ec8cdd09ca4619a0689fc5d5713a99287.zip chromium_src-bf54920ec8cdd09ca4619a0689fc5d5713a99287.tar.gz chromium_src-bf54920ec8cdd09ca4619a0689fc5d5713a99287.tar.bz2 |
Have PpapiDecryptor own the helper plugin
PpapiDecryptor now owns the Pepper helper plugin, which is wrapped in a
class so that the helper plugin is destroyed properly. This also removes
the dependency on WebMediaPlayerClientImpl to create the plugin so that
it could also be created by ContentDecryptionModule::create() for EME WD
(once we figure out how to pass the context).
BUG=250049
TEST=EME content tests pass
Review URL: https://codereview.chromium.org/138383009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253900 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/content_renderer.gypi | 3 | ||||
-rw-r--r-- | content/renderer/media/cdm_session_adapter.cc | 11 | ||||
-rw-r--r-- | content/renderer/media/cdm_session_adapter.h | 10 | ||||
-rw-r--r-- | content/renderer/media/crypto/content_decryption_module_factory.cc | 95 | ||||
-rw-r--r-- | content/renderer/media/crypto/content_decryption_module_factory.h | 24 | ||||
-rw-r--r-- | content/renderer/media/crypto/pepper_cdm_wrapper.h | 41 | ||||
-rw-r--r-- | content/renderer/media/crypto/pepper_cdm_wrapper_impl.cc | 77 | ||||
-rw-r--r-- | content/renderer/media/crypto/pepper_cdm_wrapper_impl.h | 68 | ||||
-rw-r--r-- | content/renderer/media/crypto/ppapi_decryptor.cc | 120 | ||||
-rw-r--r-- | content/renderer/media/crypto/ppapi_decryptor.h | 27 | ||||
-rw-r--r-- | content/renderer/media/crypto/proxy_decryptor.cc | 30 | ||||
-rw-r--r-- | content/renderer/media/crypto/proxy_decryptor.h | 22 | ||||
-rw-r--r-- | content/renderer/media/webcontentdecryptionmodule_impl.cc | 16 | ||||
-rw-r--r-- | content/renderer/media/webmediaplayer_impl.cc | 9 |
14 files changed, 331 insertions, 222 deletions
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index cd0bacb..e3af57f 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -233,6 +233,9 @@ 'renderer/media/crypto/key_systems.h', 'renderer/media/crypto/key_systems_support_uma.cc', 'renderer/media/crypto/key_systems_support_uma.h', + 'renderer/media/crypto/pepper_cdm_wrapper.h', + 'renderer/media/crypto/pepper_cdm_wrapper_impl.cc', + 'renderer/media/crypto/pepper_cdm_wrapper_impl.h', 'renderer/media/crypto/ppapi_decryptor.cc', 'renderer/media/crypto/ppapi_decryptor.h', 'renderer/media/crypto/proxy_decryptor.cc', diff --git a/content/renderer/media/cdm_session_adapter.cc b/content/renderer/media/cdm_session_adapter.cc index 668559a..0850694 100644 --- a/content/renderer/media/cdm_session_adapter.cc +++ b/content/renderer/media/cdm_session_adapter.cc @@ -23,16 +23,17 @@ CdmSessionAdapter::CdmSessionAdapter() : weak_ptr_factory_(this) {} CdmSessionAdapter::~CdmSessionAdapter() {} -bool CdmSessionAdapter::Initialize(const std::string& key_system) { +bool CdmSessionAdapter::Initialize( +#if defined(ENABLE_PEPPER_CDMS) + const CreatePepperCdmCB& create_pepper_cdm_cb, +#endif + const std::string& key_system) { base::WeakPtr<CdmSessionAdapter> weak_this = weak_ptr_factory_.GetWeakPtr(); media_keys_ = ContentDecryptionModuleFactory::Create( key_system, #if defined(ENABLE_PEPPER_CDMS) - // TODO(ddorwin): Support Pepper-based CDMs: http://crbug.com/250049 - NULL, - NULL, - base::Closure(), + create_pepper_cdm_cb, #elif defined(OS_ANDROID) // TODO(xhwang): Support Android. NULL, diff --git a/content/renderer/media/cdm_session_adapter.h b/content/renderer/media/cdm_session_adapter.h index 356bab4..f6f2930 100644 --- a/content/renderer/media/cdm_session_adapter.h +++ b/content/renderer/media/cdm_session_adapter.h @@ -13,6 +13,10 @@ #include "media/base/media_keys.h" #include "third_party/WebKit/public/platform/WebContentDecryptionModuleSession.h" +#if defined(ENABLE_PEPPER_CDMS) +#include "content/renderer/media/crypto/pepper_cdm_wrapper.h" +#endif + namespace content { class WebContentDecryptionModuleSessionImpl; @@ -26,7 +30,11 @@ class CdmSessionAdapter : public base::RefCounted<CdmSessionAdapter> { CdmSessionAdapter(); // Returns true on success. - bool Initialize(const std::string& key_system); + bool Initialize( +#if defined(ENABLE_PEPPER_CDMS) + const CreatePepperCdmCB& create_pepper_cdm_cb, +#endif + const std::string& key_system); // Creates a new session and adds it to the internal map. The caller owns the // created session. RemoveSession() must be called when destroying it. diff --git a/content/renderer/media/crypto/content_decryption_module_factory.cc b/content/renderer/media/crypto/content_decryption_module_factory.cc index feafca7..d076b25 100644 --- a/content/renderer/media/crypto/content_decryption_module_factory.cc +++ b/content/renderer/media/crypto/content_decryption_module_factory.cc @@ -22,81 +22,10 @@ namespace content { -#if defined(ENABLE_PEPPER_CDMS) -// Returns the PepperPluginInstanceImpl associated with the Helper Plugin. -// If a non-NULL pointer is returned, the caller must call -// closeHelperPluginSoon() when the Helper Plugin is no longer needed. -static scoped_refptr<PepperPluginInstanceImpl> CreateHelperPlugin( - const std::string& plugin_type, - blink::WebMediaPlayerClient* web_media_player_client, - blink::WebFrame* web_frame) { - DCHECK(web_media_player_client); - DCHECK(web_frame); - - blink::WebPlugin* web_plugin = web_media_player_client->createHelperPlugin( - blink::WebString::fromUTF8(plugin_type), web_frame); - if (!web_plugin) - return NULL; - - DCHECK(!web_plugin->isPlaceholder()); // Prevented by Blink. - // Only Pepper plugins are supported, so it must be a ppapi object. - PepperWebPluginImpl* ppapi_plugin = - static_cast<PepperWebPluginImpl*>(web_plugin); - return ppapi_plugin->instance(); -} - -static scoped_ptr<media::MediaKeys> CreatePpapiDecryptor( - 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, - const media::SessionErrorCB& session_error_cb, - const base::Closure& destroy_plugin_cb, - blink::WebMediaPlayerClient* web_media_player_client, - blink::WebFrame* web_frame) { - DCHECK(web_media_player_client); - DCHECK(web_frame); - - std::string plugin_type = GetPepperType(key_system); - DCHECK(!plugin_type.empty()); - const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance = - CreateHelperPlugin(plugin_type, web_media_player_client, web_frame); - if (!plugin_instance.get()) { - DLOG(ERROR) << "Plugin instance creation failed."; - return scoped_ptr<media::MediaKeys>(); - } - - scoped_ptr<PpapiDecryptor> decryptor = - PpapiDecryptor::Create(key_system, - plugin_instance, - session_created_cb, - session_message_cb, - session_ready_cb, - session_closed_cb, - session_error_cb, - destroy_plugin_cb); - - if (!decryptor) - destroy_plugin_cb.Run(); - // Else the new object will call destroy_plugin_cb to destroy Helper Plugin. - - return scoped_ptr<media::MediaKeys>(decryptor.Pass()); -} - -void ContentDecryptionModuleFactory::DestroyHelperPlugin( - blink::WebMediaPlayerClient* web_media_player_client, - blink::WebFrame* web_frame) { - web_media_player_client->closeHelperPluginSoon(web_frame); -} -#endif // defined(ENABLE_PEPPER_CDMS) - scoped_ptr<media::MediaKeys> ContentDecryptionModuleFactory::Create( const std::string& key_system, #if defined(ENABLE_PEPPER_CDMS) - blink::WebMediaPlayerClient* web_media_player_client, - blink::WebFrame* web_frame, - const base::Closure& destroy_plugin_cb, + const CreatePepperCdmCB& create_pepper_cdm_cb, #elif defined(OS_ANDROID) RendererMediaPlayerManager* manager, int media_keys_id, @@ -117,20 +46,14 @@ scoped_ptr<media::MediaKeys> ContentDecryptionModuleFactory::Create( } #if defined(ENABLE_PEPPER_CDMS) - // TODO(ddorwin): Remove when the WD API implementation supports loading - // Pepper-based CDMs: http://crbug.com/250049 - if (!web_media_player_client) - return scoped_ptr<media::MediaKeys>(); - - return CreatePpapiDecryptor(key_system, - session_created_cb, - session_message_cb, - session_ready_cb, - session_closed_cb, - session_error_cb, - destroy_plugin_cb, - web_media_player_client, - web_frame); + return scoped_ptr<media::MediaKeys>( + PpapiDecryptor::Create(key_system, + create_pepper_cdm_cb, + session_created_cb, + session_message_cb, + session_ready_cb, + session_closed_cb, + session_error_cb)); #elif defined(OS_ANDROID) scoped_ptr<ProxyMediaKeys> proxy_media_keys( new ProxyMediaKeys(manager, diff --git a/content/renderer/media/crypto/content_decryption_module_factory.h b/content/renderer/media/crypto/content_decryption_module_factory.h index 87623ca..6f32d4a 100644 --- a/content/renderer/media/crypto/content_decryption_module_factory.h +++ b/content/renderer/media/crypto/content_decryption_module_factory.h @@ -10,14 +10,11 @@ #include "base/memory/scoped_ptr.h" #include "media/base/media_keys.h" -class GURL; - #if defined(ENABLE_PEPPER_CDMS) -namespace blink { -class WebFrame; -class WebMediaPlayerClient; -} -#endif // defined(ENABLE_PEPPER_CDMS) +#include "content/renderer/media/crypto/pepper_cdm_wrapper.h" +#endif + +class GURL; namespace content { @@ -25,13 +22,12 @@ class RendererMediaPlayerManager; class ContentDecryptionModuleFactory { public: + // |create_pepper_cdm_cb| will be called synchronously if necessary. The other + // callbacks can be called asynchronously. static scoped_ptr<media::MediaKeys> Create( const std::string& key_system, #if defined(ENABLE_PEPPER_CDMS) - // TODO(ddorwin): We need different pointers for the WD API. - blink::WebMediaPlayerClient* web_media_player_client, - blink::WebFrame* web_frame, - const base::Closure& destroy_plugin_cb, + const CreatePepperCdmCB& create_pepper_cdm_cb, #elif defined(OS_ANDROID) RendererMediaPlayerManager* manager, int media_keys_id, @@ -42,12 +38,6 @@ class ContentDecryptionModuleFactory { const media::SessionReadyCB& session_ready_cb, const media::SessionClosedCB& session_closed_cb, const media::SessionErrorCB& session_error_cb); - -#if defined(ENABLE_PEPPER_CDMS) - static void DestroyHelperPlugin( - blink::WebMediaPlayerClient* web_media_player_client, - blink::WebFrame* web_frame); -#endif // defined(ENABLE_PEPPER_CDMS) }; } // namespace content diff --git a/content/renderer/media/crypto/pepper_cdm_wrapper.h b/content/renderer/media/crypto/pepper_cdm_wrapper.h new file mode 100644 index 0000000..01f0f0a --- /dev/null +++ b/content/renderer/media/crypto/pepper_cdm_wrapper.h @@ -0,0 +1,41 @@ +// Copyright 2014 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_PEPPER_CDM_WRAPPER_H_ +#define CONTENT_RENDERER_MEDIA_CRYPTO_PEPPER_CDM_WRAPPER_H_ + +#if !defined(ENABLE_PEPPER_CDMS) +#error This file should only be included when ENABLE_PEPPER_CDMS is defined +#endif + +#include <string> + +#include "base/callback.h" + +namespace content { +class ContentDecryptorDelegate; + +// PepperCdmWrapper provides access to the Pepper CDM instance. +class PepperCdmWrapper { + public: + virtual ~PepperCdmWrapper() {} + + // Returns the ContentDecryptorDelegate* associated with this plugin. + virtual ContentDecryptorDelegate* GetCdmDelegate() = 0; + + protected: + PepperCdmWrapper() {} + + private: + DISALLOW_COPY_AND_ASSIGN(PepperCdmWrapper); +}; + +// Callback used to create a PepperCdmWrapper. This may return null if the +// Pepper CDM can not be created. +typedef base::Callback<scoped_ptr<PepperCdmWrapper>( + const std::string& pluginType)> CreatePepperCdmCB; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_CRYPTO_PEPPER_CDM_WRAPPER_H_ diff --git a/content/renderer/media/crypto/pepper_cdm_wrapper_impl.cc b/content/renderer/media/crypto/pepper_cdm_wrapper_impl.cc new file mode 100644 index 0000000..f32dc03 --- /dev/null +++ b/content/renderer/media/crypto/pepper_cdm_wrapper_impl.cc @@ -0,0 +1,77 @@ +// Copyright 2014 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. + +#if defined(ENABLE_PEPPER_CDMS) +#include "content/renderer/media/crypto/pepper_cdm_wrapper_impl.h" + +#include "content/renderer/pepper/pepper_plugin_instance_impl.h" +#include "content/renderer/pepper/pepper_webplugin_impl.h" +#include "third_party/WebKit/public/platform/WebString.h" +#include "third_party/WebKit/public/web/WebDocument.h" +#include "third_party/WebKit/public/web/WebFrame.h" +#include "third_party/WebKit/public/web/WebHelperPlugin.h" +#include "third_party/WebKit/public/web/WebPlugin.h" +#include "third_party/WebKit/public/web/WebView.h" + +namespace content { + +void WebHelperPluginDeleter::operator()(blink::WebHelperPlugin* plugin) const { + plugin->destroy(); +} + +scoped_ptr<PepperCdmWrapper> PepperCdmWrapperImpl::Create( + blink::WebFrame* frame, + const std::string& pluginType) { + + // TODO(jrummell): Convert to DCHECK(frame) once Blink starts passing the + // WebFrame to WebContentDecryptionModuleImpl. + if (!frame) + return scoped_ptr<PepperCdmWrapper>(); + + ScopedHelperPlugin helper_plugin(blink::WebHelperPlugin::create( + blink::WebString::fromUTF8(pluginType), frame)); + if (!helper_plugin) + return scoped_ptr<PepperCdmWrapper>(); + + blink::WebPlugin* plugin = helper_plugin->getPlugin(); + DCHECK(!plugin->isPlaceholder()); // Prevented by Blink. + + // Only Pepper plugins are supported, so it must ultimately be a ppapi object. + PepperWebPluginImpl* ppapi_plugin = static_cast<PepperWebPluginImpl*>(plugin); + scoped_refptr<PepperPluginInstanceImpl> plugin_instance = + ppapi_plugin->instance(); + if (!plugin_instance) + return scoped_ptr<PepperCdmWrapper>(); + + if (!plugin_instance->GetContentDecryptorDelegate()) + return scoped_ptr<PepperCdmWrapper>(); + + return scoped_ptr<PepperCdmWrapper>( + new PepperCdmWrapperImpl(helper_plugin.Pass(), plugin_instance)); +} + +PepperCdmWrapperImpl::PepperCdmWrapperImpl( + ScopedHelperPlugin helper_plugin, + const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance) + : helper_plugin_(helper_plugin.Pass()), + plugin_instance_(plugin_instance) { + DCHECK(helper_plugin_); + DCHECK(plugin_instance_); + // Plugin must be a CDM. + DCHECK(plugin_instance_->GetContentDecryptorDelegate()); +} + +PepperCdmWrapperImpl::~PepperCdmWrapperImpl() { + // Destroy the nested objects in reverse order. + plugin_instance_ = NULL; + helper_plugin_.reset(); +} + +ContentDecryptorDelegate* PepperCdmWrapperImpl::GetCdmDelegate() { + return plugin_instance_->GetContentDecryptorDelegate(); +} + +} // namespace content + +#endif // defined(ENABLE_PEPPER_CDMS) diff --git a/content/renderer/media/crypto/pepper_cdm_wrapper_impl.h b/content/renderer/media/crypto/pepper_cdm_wrapper_impl.h new file mode 100644 index 0000000..df037e8 --- /dev/null +++ b/content/renderer/media/crypto/pepper_cdm_wrapper_impl.h @@ -0,0 +1,68 @@ +// Copyright 2014 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_PEPPER_CDM_WRAPPER_IMPL_H_ +#define CONTENT_RENDERER_MEDIA_CRYPTO_PEPPER_CDM_WRAPPER_IMPL_H_ + +#if !defined(ENABLE_PEPPER_CDMS) +#error This file should only be included when ENABLE_PEPPER_CDMS is defined +#endif + +#include "base/callback.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "content/renderer/media/crypto/pepper_cdm_wrapper.h" + +namespace blink { +class WebFrame; +class WebHelperPlugin; +} + +namespace content { + +class ContentDecryptorDelegate; +class PepperPluginInstanceImpl; + +// Deleter for blink::WebHelperPlugin. +struct WebHelperPluginDeleter { + void operator()(blink::WebHelperPlugin* plugin) const; +}; + +// Implements a wrapper on blink::WebHelperPlugin so that the plugin gets +// destroyed properly. It owns all the objects derived from WebHelperPlugin +// (WebPlugin, PepperPluginInstanceImpl, ContentDecryptionDelegate), and will +// free them as necessary when this wrapper is destroyed. In particular, it +// takes a reference to PepperPluginInstanceImpl so it won't go away until +// this object is destroyed. +// +// Implemented so that lower layers in Chromium don't need to be aware of +// blink:: objects. +class PepperCdmWrapperImpl : public PepperCdmWrapper { + public: + static scoped_ptr<PepperCdmWrapper> Create(blink::WebFrame* frame, + const std::string& pluginType); + + virtual ~PepperCdmWrapperImpl(); + + // Returns the ContentDecryptorDelegate* associated with this plugin. + virtual ContentDecryptorDelegate* GetCdmDelegate() OVERRIDE; + + private: + typedef scoped_ptr<blink::WebHelperPlugin, WebHelperPluginDeleter> + ScopedHelperPlugin; + + // Takes ownership of |helper_plugin| and |plugin_instance|. + PepperCdmWrapperImpl( + ScopedHelperPlugin helper_plugin, + const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance); + + ScopedHelperPlugin helper_plugin_; + scoped_refptr<PepperPluginInstanceImpl> plugin_instance_; + + DISALLOW_COPY_AND_ASSIGN(PepperCdmWrapperImpl); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_CRYPTO_PEPPER_CDM_WRAPPER_IMPL_H_ diff --git a/content/renderer/media/crypto/ppapi_decryptor.cc b/content/renderer/media/crypto/ppapi_decryptor.cc index d1fda56..4ae3686 100644 --- a/content/renderer/media/crypto/ppapi_decryptor.cc +++ b/content/renderer/media/crypto/ppapi_decryptor.cc @@ -12,6 +12,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/key_systems.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" @@ -24,62 +25,57 @@ namespace content { scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create( const std::string& key_system, - const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance, + 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, - const media::SessionErrorCB& session_error_cb, - const base::Closure& destroy_plugin_cb) { - ContentDecryptorDelegate* plugin_cdm_delegate = - plugin_instance->GetContentDecryptorDelegate(); - if (!plugin_cdm_delegate) { - DVLOG(1) << "PpapiDecryptor: plugin cdm delegate creation failed."; + const media::SessionErrorCB& session_error_cb) { + std::string plugin_type = GetPepperType(key_system); + DCHECK(!plugin_type.empty()); + scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper = + create_pepper_cdm_cb.Run(plugin_type); + if (!pepper_cdm_wrapper) { + DLOG(ERROR) << "Plugin instance creation failed."; return scoped_ptr<PpapiDecryptor>(); } - return scoped_ptr<PpapiDecryptor>(new PpapiDecryptor(key_system, - plugin_instance, - plugin_cdm_delegate, - session_created_cb, - session_message_cb, - session_ready_cb, - session_closed_cb, - session_error_cb, - destroy_plugin_cb)); + return scoped_ptr<PpapiDecryptor>( + new PpapiDecryptor(key_system, + pepper_cdm_wrapper.Pass(), + session_created_cb, + session_message_cb, + session_ready_cb, + session_closed_cb, + session_error_cb)); } PpapiDecryptor::PpapiDecryptor( const std::string& key_system, - const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance, - ContentDecryptorDelegate* plugin_cdm_delegate, + 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, - const base::Closure& destroy_plugin_cb) - : plugin_instance_(plugin_instance), - plugin_cdm_delegate_(plugin_cdm_delegate), + 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), session_error_cb_(session_error_cb), - destroy_plugin_cb_(destroy_plugin_cb), render_loop_proxy_(base::MessageLoopProxy::current()), weak_ptr_factory_(this) { - DCHECK(plugin_instance_.get()); + 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()); DCHECK(!session_error_cb_.is_null()); - DCHECK(!destroy_plugin_cb_.is_null()); weak_this_ = weak_ptr_factory_.GetWeakPtr(); - plugin_cdm_delegate_->Initialize( + CdmDelegate()->Initialize( key_system, base::Bind(&PpapiDecryptor::OnSessionCreated, weak_this_), base::Bind(&PpapiDecryptor::OnSessionMessage, weak_this_), @@ -90,10 +86,7 @@ PpapiDecryptor::PpapiDecryptor( } PpapiDecryptor::~PpapiDecryptor() { - plugin_cdm_delegate_ = NULL; - plugin_instance_ = NULL; - if (!destroy_plugin_cb_.is_null()) - base::ResetAndReturn(&destroy_plugin_cb_).Run(); + pepper_cdm_wrapper_.reset(); } bool PpapiDecryptor::CreateSession(uint32 session_id, @@ -103,9 +96,9 @@ bool PpapiDecryptor::CreateSession(uint32 session_id, DVLOG(2) << __FUNCTION__; DCHECK(render_loop_proxy_->BelongsToCurrentThread()); - if (!plugin_cdm_delegate_ || - !plugin_cdm_delegate_->CreateSession( - session_id, content_type, init_data, init_data_length)) { + if (!CdmDelegate() || + !CdmDelegate()->CreateSession( + session_id, content_type, init_data, init_data_length)) { ReportFailureToCallPlugin(session_id); return false; } @@ -118,12 +111,12 @@ void PpapiDecryptor::LoadSession(uint32 session_id, DVLOG(2) << __FUNCTION__; DCHECK(render_loop_proxy_->BelongsToCurrentThread()); - if (!plugin_cdm_delegate_) { + if (!CdmDelegate()) { ReportFailureToCallPlugin(session_id); return; } - plugin_cdm_delegate_->LoadSession(session_id, web_session_id); + CdmDelegate()->LoadSession(session_id, web_session_id); } void PpapiDecryptor::UpdateSession(uint32 session_id, @@ -132,8 +125,8 @@ void PpapiDecryptor::UpdateSession(uint32 session_id, DVLOG(2) << __FUNCTION__; DCHECK(render_loop_proxy_->BelongsToCurrentThread()); - if (!plugin_cdm_delegate_ || !plugin_cdm_delegate_->UpdateSession( - session_id, response, response_length)) { + if (!CdmDelegate() || + !CdmDelegate()->UpdateSession(session_id, response, response_length)) { ReportFailureToCallPlugin(session_id); return; } @@ -143,8 +136,7 @@ void PpapiDecryptor::ReleaseSession(uint32 session_id) { DVLOG(2) << __FUNCTION__; DCHECK(render_loop_proxy_->BelongsToCurrentThread()); - if (!plugin_cdm_delegate_ || - !plugin_cdm_delegate_->ReleaseSession(session_id)) { + if (!CdmDelegate() || !CdmDelegate()->ReleaseSession(session_id)) { ReportFailureToCallPlugin(session_id); return; } @@ -188,8 +180,8 @@ void PpapiDecryptor::Decrypt( } DVLOG(3) << __FUNCTION__ << " - stream_type: " << stream_type; - if (!plugin_cdm_delegate_ || - !plugin_cdm_delegate_->Decrypt(stream_type, encrypted, decrypt_cb)) { + if (!CdmDelegate() || + !CdmDelegate()->Decrypt(stream_type, encrypted, decrypt_cb)) { decrypt_cb.Run(kError, NULL); } } @@ -202,8 +194,8 @@ void PpapiDecryptor::CancelDecrypt(StreamType stream_type) { } DVLOG(1) << __FUNCTION__ << " - stream_type: " << stream_type; - if (plugin_cdm_delegate_) - plugin_cdm_delegate_->CancelDecrypt(stream_type); + if (CdmDelegate()) + CdmDelegate()->CancelDecrypt(stream_type); } void PpapiDecryptor::InitializeAudioDecoder( @@ -220,9 +212,11 @@ void PpapiDecryptor::InitializeAudioDecoder( DCHECK(config.IsValidConfig()); audio_decoder_init_cb_ = init_cb; - if (!plugin_cdm_delegate_ || - !plugin_cdm_delegate_->InitializeAudioDecoder(config, base::Bind( - &PpapiDecryptor::OnDecoderInitialized, weak_this_, kAudio))) { + if (!CdmDelegate() || + !CdmDelegate()->InitializeAudioDecoder( + config, + base::Bind( + &PpapiDecryptor::OnDecoderInitialized, weak_this_, kAudio))) { base::ResetAndReturn(&audio_decoder_init_cb_).Run(false); return; } @@ -242,9 +236,11 @@ void PpapiDecryptor::InitializeVideoDecoder( DCHECK(config.IsValidConfig()); video_decoder_init_cb_ = init_cb; - if (!plugin_cdm_delegate_ || - !plugin_cdm_delegate_->InitializeVideoDecoder(config, base::Bind( - &PpapiDecryptor::OnDecoderInitialized, weak_this_, kVideo))) { + if (!CdmDelegate() || + !CdmDelegate()->InitializeVideoDecoder( + config, + base::Bind( + &PpapiDecryptor::OnDecoderInitialized, weak_this_, kVideo))) { base::ResetAndReturn(&video_decoder_init_cb_).Run(false); return; } @@ -261,8 +257,8 @@ void PpapiDecryptor::DecryptAndDecodeAudio( } DVLOG(3) << __FUNCTION__; - if (!plugin_cdm_delegate_ || !plugin_cdm_delegate_->DecryptAndDecodeAudio( - encrypted, audio_decode_cb)) { + if (!CdmDelegate() || + !CdmDelegate()->DecryptAndDecodeAudio(encrypted, audio_decode_cb)) { audio_decode_cb.Run(kError, AudioBuffers()); } } @@ -278,8 +274,8 @@ void PpapiDecryptor::DecryptAndDecodeVideo( } DVLOG(3) << __FUNCTION__; - if (!plugin_cdm_delegate_ || !plugin_cdm_delegate_->DecryptAndDecodeVideo( - encrypted, video_decode_cb)) { + if (!CdmDelegate() || + !CdmDelegate()->DecryptAndDecodeVideo(encrypted, video_decode_cb)) { video_decode_cb.Run(kError, NULL); } } @@ -292,8 +288,8 @@ void PpapiDecryptor::ResetDecoder(StreamType stream_type) { } DVLOG(2) << __FUNCTION__ << " - stream_type: " << stream_type; - if (plugin_cdm_delegate_) - plugin_cdm_delegate_->ResetDecoder(stream_type); + if (CdmDelegate()) + CdmDelegate()->ResetDecoder(stream_type); } void PpapiDecryptor::DeinitializeDecoder(StreamType stream_type) { @@ -304,8 +300,8 @@ void PpapiDecryptor::DeinitializeDecoder(StreamType stream_type) { } DVLOG(2) << __FUNCTION__ << " - stream_type: " << stream_type; - if (plugin_cdm_delegate_) - plugin_cdm_delegate_->DeinitializeDecoder(stream_type); + if (CdmDelegate()) + CdmDelegate()->DeinitializeDecoder(stream_type); } void PpapiDecryptor::ReportFailureToCallPlugin(uint32 session_id) { @@ -376,10 +372,12 @@ void PpapiDecryptor::OnSessionError(uint32 session_id, void PpapiDecryptor::OnFatalPluginError() { DCHECK(render_loop_proxy_->BelongsToCurrentThread()); - DCHECK(plugin_cdm_delegate_); - plugin_cdm_delegate_ = NULL; - plugin_instance_ = NULL; - base::ResetAndReturn(&destroy_plugin_cb_).Run(); + pepper_cdm_wrapper_.reset(); +} + +ContentDecryptorDelegate* PpapiDecryptor::CdmDelegate() { + DCHECK(render_loop_proxy_->BelongsToCurrentThread()); + return (pepper_cdm_wrapper_) ? pepper_cdm_wrapper_->GetCdmDelegate() : NULL; } } // namespace content diff --git a/content/renderer/media/crypto/ppapi_decryptor.h b/content/renderer/media/crypto/ppapi_decryptor.h index f3461ef..64b45d9 100644 --- a/content/renderer/media/crypto/ppapi_decryptor.h +++ b/content/renderer/media/crypto/ppapi_decryptor.h @@ -11,6 +11,7 @@ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "content/renderer/media/crypto/pepper_cdm_wrapper.h" #include "media/base/decryptor.h" #include "media/base/media_keys.h" #include "media/base/video_decoder_config.h" @@ -29,15 +30,13 @@ class PepperPluginInstanceImpl; class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { public: static scoped_ptr<PpapiDecryptor> Create( - // TODO(ddorwin): Remove after updating the delegate. const std::string& key_system, - const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance, + 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, - const media::SessionErrorCB& session_error_cb, - const base::Closure& destroy_plugin_cb); + const media::SessionErrorCB& session_error_cb); virtual ~PpapiDecryptor(); @@ -76,14 +75,12 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { private: PpapiDecryptor(const std::string& key_system, - const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance, - ContentDecryptorDelegate* plugin_cdm_delegate, + 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, - const base::Closure& destroy_plugin_cb); + const media::SessionErrorCB& session_error_cb); void ReportFailureToCallPlugin(uint32 session_id); @@ -105,14 +102,13 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { // this call. void OnFatalPluginError(); - base::WeakPtr<PpapiDecryptor> weak_this_; + ContentDecryptorDelegate* CdmDelegate(); - // Hold a reference of the plugin instance to make sure the plugin outlives - // the |plugin_cdm_delegate_|. This is needed because |plugin_cdm_delegate_| - // is owned by the |plugin_instance_|. - scoped_refptr<PepperPluginInstanceImpl> plugin_instance_; + base::WeakPtr<PpapiDecryptor> weak_this_; - ContentDecryptorDelegate* plugin_cdm_delegate_; + // Hold a reference of the Pepper CDM wrapper to make sure the plugin lives + // as long as needed. + scoped_ptr<PepperCdmWrapper> pepper_cdm_wrapper_; // Callbacks for firing session events. media::SessionCreatedCB session_created_cb_; @@ -121,9 +117,6 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { media::SessionClosedCB session_closed_cb_; media::SessionErrorCB session_error_cb_; - // Called to destroy the helper plugin when this class no longer needs it. - base::Closure destroy_plugin_cb_; - scoped_refptr<base::MessageLoopProxy> render_loop_proxy_; DecoderInitCB audio_decoder_init_cb_; diff --git a/content/renderer/media/crypto/proxy_decryptor.cc b/content/renderer/media/crypto/proxy_decryptor.cc index 4237fe6..f274119 100644 --- a/content/renderer/media/crypto/proxy_decryptor.cc +++ b/content/renderer/media/crypto/proxy_decryptor.cc @@ -11,11 +11,16 @@ #include "base/logging.h" #include "base/strings/string_util.h" #include "content/renderer/media/crypto/content_decryption_module_factory.h" +#include "media/cdm/json_web_key.h" +#include "media/cdm/key_system_names.h" + +#if defined(ENABLE_PEPPER_CDMS) +#include "content/renderer/media/crypto/pepper_cdm_wrapper.h" +#endif // defined(ENABLE_PEPPER_CDMS) + #if defined(OS_ANDROID) #include "content/renderer/media/android/renderer_media_player_manager.h" #endif // defined(OS_ANDROID) -#include "media/cdm/json_web_key.h" -#include "media/cdm/key_system_names.h" namespace content { @@ -32,17 +37,9 @@ const uint32 kInvalidSessionId = 0; // EME API. const int kSessionClosedSystemCode = 29127; -#if defined(ENABLE_PEPPER_CDMS) -void ProxyDecryptor::DestroyHelperPlugin() { - ContentDecryptionModuleFactory::DestroyHelperPlugin( - web_media_player_client_, web_frame_); -} -#endif // defined(ENABLE_PEPPER_CDMS) - ProxyDecryptor::ProxyDecryptor( #if defined(ENABLE_PEPPER_CDMS) - blink::WebMediaPlayerClient* web_media_player_client, - blink::WebFrame* web_frame, + const CreatePepperCdmCB& create_pepper_cdm_cb, #elif defined(OS_ANDROID) RendererMediaPlayerManager* manager, int media_keys_id, @@ -52,8 +49,7 @@ ProxyDecryptor::ProxyDecryptor( const KeyMessageCB& key_message_cb) : weak_ptr_factory_(this), #if defined(ENABLE_PEPPER_CDMS) - web_media_player_client_(web_media_player_client), - web_frame_(web_frame), + create_pepper_cdm_cb_(create_pepper_cdm_cb), #elif defined(OS_ANDROID) manager_(manager), media_keys_id_(media_keys_id), @@ -62,6 +58,9 @@ ProxyDecryptor::ProxyDecryptor( key_error_cb_(key_error_cb), key_message_cb_(key_message_cb), is_clear_key_(false) { +#if defined(ENABLE_PEPPER_CDMS) + DCHECK(!create_pepper_cdm_cb_.is_null()); +#endif // defined(ENABLE_PEPPER_CDMS) DCHECK(!key_added_cb_.is_null()); DCHECK(!key_error_cb_.is_null()); DCHECK(!key_message_cb_.is_null()); @@ -188,10 +187,7 @@ scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys( return ContentDecryptionModuleFactory::Create( key_system, #if defined(ENABLE_PEPPER_CDMS) - web_media_player_client_, - web_frame_, - base::Bind(&ProxyDecryptor::DestroyHelperPlugin, - weak_ptr_factory_.GetWeakPtr()), + create_pepper_cdm_cb_, #elif defined(OS_ANDROID) manager_, media_keys_id_, diff --git a/content/renderer/media/crypto/proxy_decryptor.h b/content/renderer/media/crypto/proxy_decryptor.h index 1256ada..f817629 100644 --- a/content/renderer/media/crypto/proxy_decryptor.h +++ b/content/renderer/media/crypto/proxy_decryptor.h @@ -17,14 +17,11 @@ #include "media/base/decryptor.h" #include "media/base/media_keys.h" -class GURL; - -namespace blink { #if defined(ENABLE_PEPPER_CDMS) -class WebFrame; -class WebMediaPlayerClient; -#endif // defined(ENABLE_PEPPER_CDMS) -} +#include "content/renderer/media/crypto/pepper_cdm_wrapper.h" +#endif + +class GURL; namespace content { @@ -59,8 +56,7 @@ class ProxyDecryptor { ProxyDecryptor( #if defined(ENABLE_PEPPER_CDMS) - blink::WebMediaPlayerClient* web_media_player_client, - blink::WebFrame* web_frame, + const CreatePepperCdmCB& create_pepper_cdm_cb, #elif defined(OS_ANDROID) RendererMediaPlayerManager* manager, int media_keys_id, @@ -116,12 +112,8 @@ class ProxyDecryptor { base::WeakPtrFactory<ProxyDecryptor> weak_ptr_factory_; #if defined(ENABLE_PEPPER_CDMS) - // Callback for cleaning up a Pepper-based CDM. - void DestroyHelperPlugin(); - - // Needed to create the PpapiDecryptor. - blink::WebMediaPlayerClient* web_media_player_client_; - blink::WebFrame* web_frame_; + // Callback to create the Pepper plugin. + CreatePepperCdmCB create_pepper_cdm_cb_; #elif defined(OS_ANDROID) RendererMediaPlayerManager* manager_; int media_keys_id_; diff --git a/content/renderer/media/webcontentdecryptionmodule_impl.cc b/content/renderer/media/webcontentdecryptionmodule_impl.cc index c860e8e..7b2131b 100644 --- a/content/renderer/media/webcontentdecryptionmodule_impl.cc +++ b/content/renderer/media/webcontentdecryptionmodule_impl.cc @@ -8,12 +8,17 @@ #include <vector> #include "base/basictypes.h" +#include "base/bind.h" #include "base/logging.h" #include "base/strings/string_util.h" #include "content/renderer/media/cdm_session_adapter.h" #include "content/renderer/media/webcontentdecryptionmodulesession_impl.h" #include "media/base/media_keys.h" +#if defined(ENABLE_PEPPER_CDMS) +#include "content/renderer/media/crypto/pepper_cdm_wrapper_impl.h" +#endif + namespace content { WebContentDecryptionModuleImpl* WebContentDecryptionModuleImpl::Create( @@ -26,8 +31,17 @@ WebContentDecryptionModuleImpl* WebContentDecryptionModuleImpl::Create( } scoped_refptr<CdmSessionAdapter> adapter(new CdmSessionAdapter()); - if (!adapter->Initialize(UTF16ToASCII(key_system))) + if (!adapter->Initialize( +#if defined(ENABLE_PEPPER_CDMS) + // TODO(jrummell): Figure out how to get a WebFrame from Blink (or + // something equivalent) so the plugin can actually get created. + // http://crbug.com/250049 + base::Bind(&PepperCdmWrapperImpl::Create, + static_cast<blink::WebFrame*>(NULL)), +#endif + UTF16ToASCII(key_system))) { return NULL; + } return new WebContentDecryptionModuleImpl(adapter); } diff --git a/content/renderer/media/webmediaplayer_impl.cc b/content/renderer/media/webmediaplayer_impl.cc index a034bce..215148a 100644 --- a/content/renderer/media/webmediaplayer_impl.cc +++ b/content/renderer/media/webmediaplayer_impl.cc @@ -69,6 +69,10 @@ #include "v8/include/v8.h" #include "webkit/renderer/compositor_bindings/web_layer_impl.h" +#if defined(ENABLE_PEPPER_CDMS) +#include "content/renderer/media/crypto/pepper_cdm_wrapper_impl.h" +#endif + using blink::WebCanvas; using blink::WebMediaPlayer; using blink::WebRect; @@ -764,8 +768,9 @@ WebMediaPlayerImpl::GenerateKeyRequestInternal(const std::string& key_system, if (!proxy_decryptor_) { proxy_decryptor_.reset(new ProxyDecryptor( #if defined(ENABLE_PEPPER_CDMS) - client_, - frame_, + // Create() must be called synchronously as |frame_| may not be + // valid afterwards. + base::Bind(&PepperCdmWrapperImpl::Create, frame_), #endif BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyAdded), BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnKeyError), |