From 0727f762cadc51cadb4a352f00f60ebb9cbb488c Mon Sep 17 00:00:00 2001 From: "xhwang@chromium.org" Date: Mon, 31 Mar 2014 17:43:19 +0000 Subject: [PATCH] Encrypted Media: Implement IPC based SetCdm(). BUG=338910 Review URL: https://codereview.chromium.org/193523002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260592 0039d316-1c4b-4281-b951-d872f2087c98 --- .../android/browser_media_player_manager.cc | 19 ++++++---- .../android/browser_media_player_manager.h | 5 +-- .../media/media_player_messages_android.h | 5 +++ .../media/android/proxy_media_keys.cc | 10 ++++- .../renderer/media/android/proxy_media_keys.h | 7 +++- .../android/renderer_media_player_manager.cc | 11 ++++++ .../android/renderer_media_player_manager.h | 7 ++++ .../media/android/webmediaplayer_android.cc | 37 ++++++++++++++++--- .../media/android/webmediaplayer_android.h | 18 +++++++-- content/renderer/media/cdm_session_adapter.cc | 16 ++++++-- content/renderer/media/cdm_session_adapter.h | 14 ++++++- .../content_decryption_module_factory.cc | 8 ++-- .../content_decryption_module_factory.h | 2 +- .../renderer/media/crypto/proxy_decryptor.cc | 11 ++++-- .../renderer/media/crypto/proxy_decryptor.h | 7 +++- .../media/webcontentdecryptionmodule_impl.cc | 10 ++++- .../media/webcontentdecryptionmodule_impl.h | 6 +++ content/renderer/media/webmediaplayer_impl.cc | 2 +- content/renderer/media/webmediaplayer_impl.h | 1 + 19 files changed, 157 insertions(+), 39 deletions(-) diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc index 40e18250858e3e..24fb708b3deab7 100644 --- a/content/browser/media/android/browser_media_player_manager.cc +++ b/content/browser/media/android/browser_media_player_manager.cc @@ -149,6 +149,7 @@ bool BrowserMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyMediaPlayer, OnDestroyPlayer) IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers, DestroyAllMediaPlayers) + IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetCdm, OnSetCdm) IPC_MESSAGE_HANDLER(CdmHostMsg_InitializeCdm, OnInitializeCdm) IPC_MESSAGE_HANDLER(CdmHostMsg_CreateSession, OnCreateSession) IPC_MESSAGE_HANDLER(CdmHostMsg_UpdateSession, OnUpdateSession) @@ -522,10 +523,14 @@ void BrowserMediaPlayerManager::OnInitialize( RenderProcessHostImpl* host = static_cast( web_contents()->GetRenderProcessHost()); - AddPlayer(CreateMediaPlayer( + MediaPlayerAndroid* player = CreateMediaPlayer( type, player_id, url, first_party_for_cookies, demuxer_client_id, host->GetBrowserContext()->IsOffTheRecord(), this, - host->browser_demuxer_android())); + host->browser_demuxer_android()); + if (!player) + return; + + AddPlayer(player); } void BrowserMediaPlayerManager::OnStart(int player_id) { @@ -590,9 +595,6 @@ void BrowserMediaPlayerManager::OnInitializeCdm(int cdm_id, } AddDrmBridge(cdm_id, key_system, frame_url); - // In EME v0.1b MediaKeys lives in the media element. So the |cdm_id| - // is the same as the |player_id|. - OnSetMediaKeys(cdm_id, cdm_id); } void BrowserMediaPlayerManager::OnCreateSession( @@ -781,13 +783,14 @@ void BrowserMediaPlayerManager::RemoveDrmBridge(int cdm_id) { } } -void BrowserMediaPlayerManager::OnSetMediaKeys(int player_id, int cdm_id) { +void BrowserMediaPlayerManager::OnSetCdm(int player_id, int cdm_id) { MediaPlayerAndroid* player = GetPlayer(player_id); MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id); - if (!player || !drm_bridge) { - DVLOG(1) << "OnSetMediaKeys(): Player and MediaKeys must be present."; + if (!drm_bridge || !player) { + DVLOG(1) << "Cannot set CDM on the specified player."; return; } + // TODO(qinmin): add the logic to decide whether we should create the // fullscreen surface for EME lv1. player->SetDrmBridge(drm_bridge); diff --git a/content/browser/media/android/browser_media_player_manager.h b/content/browser/media/android/browser_media_player_manager.h index 235d9ce16f3be5..8fa1b17323c02a 100644 --- a/content/browser/media/android/browser_media_player_manager.h +++ b/content/browser/media/android/browser_media_player_manager.h @@ -5,7 +5,6 @@ #ifndef CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_MEDIA_PLAYER_MANAGER_H_ #define CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_MEDIA_PLAYER_MANAGER_H_ -#include #include #include #include @@ -147,7 +146,7 @@ class CONTENT_EXPORT BrowserMediaPlayerManager uint32 session_id, const std::vector& response); void OnReleaseSession(int cdm_id, uint32 session_id); - void OnSetMediaKeys(int player_id, int cdm_id); + void OnSetCdm(int player_id, int cdm_id); void OnDestroyCdm(int cdm_id); // Cancels all pending session creations associated with |cdm_id|. @@ -220,7 +219,7 @@ class CONTENT_EXPORT BrowserMediaPlayerManager // An array of managed media DRM bridges. ScopedVector drm_bridges_; - // a set of media keys IDs that are pending approval or approved to access + // A set of media keys IDs that are pending approval or approved to access // device DRM credentials. // These 2 sets does not cover all the EME videos. If a video only streams // clear data, it will not be included in either set. diff --git a/content/common/media/media_player_messages_android.h b/content/common/media/media_player_messages_android.h index 05177ba0946a9f..60fb274b954497 100644 --- a/content/common/media/media_player_messages_android.h +++ b/content/common/media/media_player_messages_android.h @@ -250,6 +250,11 @@ IPC_MESSAGE_ROUTED1(MediaPlayerHostMsg_EnterFullscreen, int /* player_id */) // Requests the player to exit fullscreen. IPC_MESSAGE_ROUTED1(MediaPlayerHostMsg_ExitFullscreen, int /* player_id */) +// Requests the player with |player_id| to use the CDM with |cdm_id|. +IPC_MESSAGE_ROUTED2(MediaPlayerHostMsg_SetCdm, + int /* player_id */, + int /* cdm_id */); + // Sent after the renderer demuxer has seeked. IPC_MESSAGE_CONTROL2(MediaPlayerHostMsg_DemuxerSeekDone, int /* demuxer_client_id */, diff --git a/content/renderer/media/android/proxy_media_keys.cc b/content/renderer/media/android/proxy_media_keys.cc index 9734e815e785ab..bd498a0d9694e1 100644 --- a/content/renderer/media/android/proxy_media_keys.cc +++ b/content/renderer/media/android/proxy_media_keys.cc @@ -13,16 +13,18 @@ namespace content { +int ProxyMediaKeys::next_cdm_id_ = + RendererMediaPlayerManager::kInvalidCdmId + 1; + ProxyMediaKeys::ProxyMediaKeys( RendererMediaPlayerManager* manager, - int cdm_id, 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) : manager_(manager), - cdm_id_(cdm_id), + cdm_id_(next_cdm_id_++), session_created_cb_(session_created_cb), session_message_cb_(session_message_cb), session_ready_cb_(session_ready_cb), @@ -111,4 +113,8 @@ void ProxyMediaKeys::OnSessionError(uint32 session_id, session_error_cb_.Run(session_id, error_code, system_code); } +int ProxyMediaKeys::GetCdmId() const { + return cdm_id_; +} + } // namespace content diff --git a/content/renderer/media/android/proxy_media_keys.h b/content/renderer/media/android/proxy_media_keys.h index dd0f99e9f91b4f..74ae52e60e0e8f 100644 --- a/content/renderer/media/android/proxy_media_keys.h +++ b/content/renderer/media/android/proxy_media_keys.h @@ -21,7 +21,6 @@ class RendererMediaPlayerManager; class ProxyMediaKeys : public media::MediaKeys { public: ProxyMediaKeys(RendererMediaPlayerManager* proxy, - int cdm_id, const media::SessionCreatedCB& session_created_cb, const media::SessionMessageCB& session_message_cb, const media::SessionReadyCB& session_ready_cb, @@ -54,7 +53,13 @@ class ProxyMediaKeys : public media::MediaKeys { media::MediaKeys::KeyError error_code, uint32 system_code); + int GetCdmId() const; + private: + // CDM ID should be unique per renderer process. + // TODO(xhwang): Use uint32 to prevent undefined overflow behavior. + static int next_cdm_id_; + RendererMediaPlayerManager* manager_; int cdm_id_; media::SessionCreatedCB session_created_cb_; diff --git a/content/renderer/media/android/renderer_media_player_manager.cc b/content/renderer/media/android/renderer_media_player_manager.cc index 614d9e66d4ffef..7c2ba0a87b1da8 100644 --- a/content/renderer/media/android/renderer_media_player_manager.cc +++ b/content/renderer/media/android/renderer_media_player_manager.cc @@ -240,10 +240,17 @@ void RendererMediaPlayerManager::ExitFullscreen(int player_id) { Send(new MediaPlayerHostMsg_ExitFullscreen(routing_id(), player_id)); } +void RendererMediaPlayerManager::SetCdm(int player_id, int cdm_id) { + if (cdm_id == kInvalidCdmId) + return; + Send(new MediaPlayerHostMsg_SetCdm(routing_id(), player_id, cdm_id)); +} + void RendererMediaPlayerManager::InitializeCdm(int cdm_id, ProxyMediaKeys* media_keys, const std::string& key_system, const GURL& frame_url) { + DCHECK_NE(cdm_id, kInvalidCdmId); RegisterMediaKeys(cdm_id, media_keys); Send(new CdmHostMsg_InitializeCdm( routing_id(), cdm_id, key_system, frame_url)); @@ -254,6 +261,7 @@ void RendererMediaPlayerManager::CreateSession( uint32 session_id, CdmHostMsg_CreateSession_ContentType content_type, const std::vector& init_data) { + DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; Send(new CdmHostMsg_CreateSession( routing_id(), cdm_id, session_id, content_type, init_data)); } @@ -262,15 +270,18 @@ void RendererMediaPlayerManager::UpdateSession( int cdm_id, uint32 session_id, const std::vector& response) { + DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; Send( new CdmHostMsg_UpdateSession(routing_id(), cdm_id, session_id, response)); } void RendererMediaPlayerManager::ReleaseSession(int cdm_id, uint32 session_id) { + DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; Send(new CdmHostMsg_ReleaseSession(routing_id(), cdm_id, session_id)); } void RendererMediaPlayerManager::DestroyCdm(int cdm_id) { + DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; Send(new CdmHostMsg_DestroyCdm(routing_id(), cdm_id)); } diff --git a/content/renderer/media/android/renderer_media_player_manager.h b/content/renderer/media/android/renderer_media_player_manager.h index ed94b7639ac95d..1ad82ebe93bfe4 100644 --- a/content/renderer/media/android/renderer_media_player_manager.h +++ b/content/renderer/media/android/renderer_media_player_manager.h @@ -35,6 +35,8 @@ class WebMediaPlayerAndroid; // RenderView. class RendererMediaPlayerManager : public RenderViewObserver { public: + static const int kInvalidCdmId = 0; + // Constructs a RendererMediaPlayerManager object for the |render_view|. RendererMediaPlayerManager(RenderView* render_view); virtual ~RendererMediaPlayerManager(); @@ -80,6 +82,11 @@ class RendererMediaPlayerManager : public RenderViewObserver { // Requests the player to exit fullscreen. void ExitFullscreen(int player_id); + // Requests the player with |player_id| to use the CDM with |cdm_id|. + // Does nothing if |cdm_id| is kInvalidCdmId. + // TODO(xhwang): Update this when we implement setCdm(0). + void SetCdm(int player_id, int cdm_id); + #if defined(VIDEO_HOLE) // Requests an external surface for out-of-band compositing. void RequestExternalSurface(int player_id, const gfx::RectF& geometry); diff --git a/content/renderer/media/android/webmediaplayer_android.cc b/content/renderer/media/android/webmediaplayer_android.cc index c107d326f00bff..323d517e00e127 100644 --- a/content/renderer/media/android/webmediaplayer_android.cc +++ b/content/renderer/media/android/webmediaplayer_android.cc @@ -18,10 +18,10 @@ #include "cc/layers/video_layer.h" #include "content/public/common/content_client.h" #include "content/public/renderer/render_frame.h" -#include "content/renderer/media/android/proxy_media_keys.h" #include "content/renderer/media/android/renderer_demuxer_android.h" #include "content/renderer/media/android/renderer_media_player_manager.h" #include "content/renderer/media/crypto/key_systems.h" +#include "content/renderer/media/webcontentdecryptionmodule_impl.h" #include "content/renderer/media/webmediaplayer_delegate.h" #include "content/renderer/media/webmediaplayer_util.h" #include "content/renderer/render_frame_impl.h" @@ -31,6 +31,8 @@ #include "gpu/command_buffer/common/mailbox_holder.h" #include "media/base/android/media_player_android.h" #include "media/base/bind_to_current_loop.h" +// TODO(xhwang): Remove when we remove prefixed EME implementation. +#include "media/base/media_keys.h" #include "media/base/media_switches.h" #include "media/base/video_frame.h" #include "net/base/mime_util.h" @@ -106,6 +108,7 @@ WebMediaPlayerAndroid::WebMediaPlayerAndroid( current_time_(0), is_remote_(false), media_log_(media_log), + web_cdm_(NULL), weak_factory_(this) { DCHECK(manager_); @@ -1268,8 +1271,6 @@ WebMediaPlayerAndroid::GenerateKeyRequestInternal( frame_, #else manager_, - player_id_, // TODO(xhwang): Use cdm_id when MediaKeys are - // separated from WebMediaPlayer. #endif // defined(ENABLE_PEPPER_CDMS) base::Bind(&WebMediaPlayerAndroid::OnKeyAdded, weak_factory_.GetWeakPtr()), @@ -1284,11 +1285,12 @@ WebMediaPlayerAndroid::GenerateKeyRequestInternal( return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported; } - if (proxy_decryptor_ && !decryptor_ready_cb_.is_null()) { + if (!decryptor_ready_cb_.is_null()) { base::ResetAndReturn(&decryptor_ready_cb_) .Run(proxy_decryptor_->GetDecryptor()); } + manager_->SetCdm(player_id_, proxy_decryptor_->GetCdmId()); current_key_system_ = key_system; } else if (key_system != current_key_system_) { return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState; @@ -1388,6 +1390,24 @@ WebMediaPlayerAndroid::CancelKeyRequestInternal(const std::string& key_system, return WebMediaPlayer::MediaKeyExceptionNoError; } +void WebMediaPlayerAndroid::setContentDecryptionModule( + blink::WebContentDecryptionModule* cdm) { + DCHECK(main_thread_checker_.CalledOnValidThread()); + + // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324 + if (!cdm) + return; + + web_cdm_ = ToWebContentDecryptionModuleImpl(cdm); + if (!web_cdm_) + return; + + if (!decryptor_ready_cb_.is_null()) + base::ResetAndReturn(&decryptor_ready_cb_).Run(web_cdm_->GetDecryptor()); + + manager_->SetCdm(player_id_, web_cdm_->GetCdmId()); +} + void WebMediaPlayerAndroid::OnKeyAdded(const std::string& session_id) { EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1); @@ -1476,13 +1496,18 @@ void WebMediaPlayerAndroid::SetDecryptorReadyCB( // detail. DCHECK(decryptor_ready_cb_.is_null()); + // Mixed use of prefixed and unprefixed EME APIs is disallowed by Blink. + DCHECK(!proxy_decryptor_ || !web_cdm_); + if (proxy_decryptor_) { decryptor_ready_cb.Run(proxy_decryptor_->GetDecryptor()); return; } - // TODO(xhwang): Also notify |web_cdm_| when we implement - // setContentDecryptionModule(). See: http://crbug.com/224786 + if (web_cdm_) { + decryptor_ready_cb.Run(web_cdm_->GetDecryptor()); + return; + } decryptor_ready_cb_ = decryptor_ready_cb; } diff --git a/content/renderer/media/android/webmediaplayer_android.h b/content/renderer/media/android/webmediaplayer_android.h index 3ccf5ce9d22576..89808a7c15a250 100644 --- a/content/renderer/media/android/webmediaplayer_android.h +++ b/content/renderer/media/android/webmediaplayer_android.h @@ -36,6 +36,7 @@ class MessageLoopProxy; } namespace blink { +class WebContentDecryptionModule; class WebFrame; class WebURL; } @@ -53,8 +54,9 @@ class WebLayerImpl; } namespace content { -class WebMediaPlayerDelegate; class RendererMediaPlayerManager; +class WebContentDecryptionModuleImpl; +class WebMediaPlayerDelegate; // This class implements blink::WebMediaPlayer by keeping the android // media player in the browser process. It listens to all the status changes @@ -214,6 +216,8 @@ class WebMediaPlayerAndroid : public blink::WebMediaPlayer, virtual MediaKeyException cancelKeyRequest( const blink::WebString& key_system, const blink::WebString& session_id); + virtual void setContentDecryptionModule( + blink::WebContentDecryptionModule* cdm); void OnKeyAdded(const std::string& session_id); void OnKeyError(const std::string& session_id, @@ -427,11 +431,19 @@ class WebMediaPlayerAndroid : public blink::WebMediaPlayer, // through GenerateKeyRequest() directly from WebKit. std::string init_data_type_; - media::DecryptorReadyCB decryptor_ready_cb_; - // Manages decryption keys and decrypts encrypted frames. scoped_ptr proxy_decryptor_; + // Non-owned pointer to the CDM. Updated via calls to + // setContentDecryptionModule(). + WebContentDecryptionModuleImpl* web_cdm_; + + // This is only Used by Clear Key key system implementation, where a renderer + // side CDM will be used. This is similar to WebMediaPlayerImpl. For other key + // systems, a browser side CDM will be used and we set CDM by calling + // manager_->SetCdm() directly. + media::DecryptorReadyCB decryptor_ready_cb_; + // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; diff --git a/content/renderer/media/cdm_session_adapter.cc b/content/renderer/media/cdm_session_adapter.cc index b77cb3805dd58d..473a53b48fc382 100644 --- a/content/renderer/media/cdm_session_adapter.cc +++ b/content/renderer/media/cdm_session_adapter.cc @@ -19,14 +19,18 @@ uint32 CdmSessionAdapter::next_session_id_ = kStartingSessionId; COMPILE_ASSERT(kStartingSessionId > media::MediaKeys::kInvalidSessionId, invalid_starting_value); -CdmSessionAdapter::CdmSessionAdapter() : weak_ptr_factory_(this) {} +CdmSessionAdapter::CdmSessionAdapter() : +#if defined(OS_ANDROID) + cdm_id_(0), +#endif + weak_ptr_factory_(this) {} CdmSessionAdapter::~CdmSessionAdapter() {} bool CdmSessionAdapter::Initialize( #if defined(ENABLE_PEPPER_CDMS) const CreatePepperCdmCB& create_pepper_cdm_cb, -#endif +#endif // defined(ENABLE_PEPPER_CDMS) const std::string& key_system) { base::WeakPtr weak_this = weak_ptr_factory_.GetWeakPtr(); media_keys_ = @@ -37,9 +41,9 @@ bool CdmSessionAdapter::Initialize( #elif defined(OS_ANDROID) // TODO(xhwang): Support Android. NULL, - 0, // TODO(ddorwin): Get the URL for the frame containing the MediaKeys. GURL(), + &cdm_id_, #endif // defined(ENABLE_PEPPER_CDMS) base::Bind(&CdmSessionAdapter::OnSessionCreated, weak_this), base::Bind(&CdmSessionAdapter::OnSessionMessage, weak_this), @@ -92,6 +96,12 @@ media::Decryptor* CdmSessionAdapter::GetDecryptor() { return media_keys_->GetDecryptor(); } +#if defined(OS_ANDROID) +int CdmSessionAdapter::GetCdmId() const { + return cdm_id_; +} +#endif // defined(OS_ANDROID) + void CdmSessionAdapter::OnSessionCreated(uint32 session_id, const std::string& web_session_id) { WebContentDecryptionModuleSessionImpl* session = GetSession(session_id); diff --git a/content/renderer/media/cdm_session_adapter.h b/content/renderer/media/cdm_session_adapter.h index 9c8ae0a5ee04b0..b0443a0b8bb150 100644 --- a/content/renderer/media/cdm_session_adapter.h +++ b/content/renderer/media/cdm_session_adapter.h @@ -65,6 +65,12 @@ class CdmSessionAdapter : public base::RefCounted { // after WebContentDecryptionModule is freed. http://crbug.com/330324 media::Decryptor* GetDecryptor(); +#if defined(OS_ANDROID) + // Returns the CDM ID associated with the |media_keys_|. May be kInvalidCdmId + // if no CDM ID is associated. + int GetCdmId() const; +#endif + private: friend class base::RefCounted; typedef std::map SessionMap; @@ -85,12 +91,16 @@ class CdmSessionAdapter : public base::RefCounted { // Helper function of the callbacks. WebContentDecryptionModuleSessionImpl* GetSession(uint32 session_id); + // Session ID should be unique per renderer process for debugging purposes. + static uint32 next_session_id_; + scoped_ptr media_keys_; SessionMap sessions_; - // Session ID should be unique per renderer process for debugging purposes. - static uint32 next_session_id_; +#if defined(OS_ANDROID) + int cdm_id_; +#endif // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_ptr_factory_; diff --git a/content/renderer/media/crypto/content_decryption_module_factory.cc b/content/renderer/media/crypto/content_decryption_module_factory.cc index 68f887aea35900..77aad29c91a34e 100644 --- a/content/renderer/media/crypto/content_decryption_module_factory.cc +++ b/content/renderer/media/crypto/content_decryption_module_factory.cc @@ -28,14 +28,17 @@ scoped_ptr ContentDecryptionModuleFactory::Create( const CreatePepperCdmCB& create_pepper_cdm_cb, #elif defined(OS_ANDROID) RendererMediaPlayerManager* manager, - int cdm_id, const GURL& frame_url, + int* cdm_id, #endif // defined(ENABLE_PEPPER_CDMS) 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) { +#if defined(OS_ANDROID) + *cdm_id = RendererMediaPlayerManager::kInvalidCdmId; +#endif if (CanUseAesDecryptor(key_system)) { return scoped_ptr( new media::AesDecryptor(session_created_cb, @@ -44,7 +47,6 @@ scoped_ptr ContentDecryptionModuleFactory::Create( session_closed_cb, session_error_cb)); } - #if defined(ENABLE_PEPPER_CDMS) return scoped_ptr( PpapiDecryptor::Create(key_system, @@ -57,13 +59,13 @@ scoped_ptr ContentDecryptionModuleFactory::Create( #elif defined(OS_ANDROID) scoped_ptr proxy_media_keys( new ProxyMediaKeys(manager, - cdm_id, session_created_cb, session_message_cb, session_ready_cb, session_closed_cb, session_error_cb)); proxy_media_keys->InitializeCdm(key_system, frame_url); + *cdm_id = proxy_media_keys->GetCdmId(); return proxy_media_keys.PassAs(); #else return scoped_ptr(); diff --git a/content/renderer/media/crypto/content_decryption_module_factory.h b/content/renderer/media/crypto/content_decryption_module_factory.h index 418c5e561d8594..df3f34e20c80eb 100644 --- a/content/renderer/media/crypto/content_decryption_module_factory.h +++ b/content/renderer/media/crypto/content_decryption_module_factory.h @@ -30,8 +30,8 @@ class ContentDecryptionModuleFactory { const CreatePepperCdmCB& create_pepper_cdm_cb, #elif defined(OS_ANDROID) RendererMediaPlayerManager* manager, - int cdm_id, const GURL& frame_url, + int* cdm_id, // Output parameter indicating the CDM ID of the MediaKeys. #endif // defined(ENABLE_PEPPER_CDMS) const media::SessionCreatedCB& session_created_cb, const media::SessionMessageCB& session_message_cb, diff --git a/content/renderer/media/crypto/proxy_decryptor.cc b/content/renderer/media/crypto/proxy_decryptor.cc index 72b11581201fe3..189d8ad2b686ae 100644 --- a/content/renderer/media/crypto/proxy_decryptor.cc +++ b/content/renderer/media/crypto/proxy_decryptor.cc @@ -42,7 +42,6 @@ ProxyDecryptor::ProxyDecryptor( const CreatePepperCdmCB& create_pepper_cdm_cb, #elif defined(OS_ANDROID) RendererMediaPlayerManager* manager, - int cdm_id, #endif // defined(ENABLE_PEPPER_CDMS) const KeyAddedCB& key_added_cb, const KeyErrorCB& key_error_cb, @@ -52,7 +51,7 @@ ProxyDecryptor::ProxyDecryptor( create_pepper_cdm_cb_(create_pepper_cdm_cb), #elif defined(OS_ANDROID) manager_(manager), - cdm_id_(cdm_id), + cdm_id_(RendererMediaPlayerManager::kInvalidCdmId), #endif // defined(ENABLE_PEPPER_CDMS) key_added_cb_(key_added_cb), key_error_cb_(key_error_cb), @@ -76,6 +75,12 @@ media::Decryptor* ProxyDecryptor::GetDecryptor() { return media_keys_ ? media_keys_->GetDecryptor() : NULL; } +#if defined(OS_ANDROID) +int ProxyDecryptor::GetCdmId() { + return cdm_id_; +} +#endif + bool ProxyDecryptor::InitializeCDM(const std::string& key_system, const GURL& frame_url) { DVLOG(1) << "InitializeCDM: key_system = " << key_system; @@ -191,8 +196,8 @@ scoped_ptr ProxyDecryptor::CreateMediaKeys( create_pepper_cdm_cb_, #elif defined(OS_ANDROID) manager_, - cdm_id_, frame_url, + &cdm_id_, #endif // defined(ENABLE_PEPPER_CDMS) base::Bind(&ProxyDecryptor::OnSessionCreated, weak_ptr_factory_.GetWeakPtr()), diff --git a/content/renderer/media/crypto/proxy_decryptor.h b/content/renderer/media/crypto/proxy_decryptor.h index 14535e0d8ca775..c07af0ac560dee 100644 --- a/content/renderer/media/crypto/proxy_decryptor.h +++ b/content/renderer/media/crypto/proxy_decryptor.h @@ -59,7 +59,6 @@ class ProxyDecryptor { const CreatePepperCdmCB& create_pepper_cdm_cb, #elif defined(OS_ANDROID) RendererMediaPlayerManager* manager, - int cdm_id, #endif // defined(ENABLE_PEPPER_CDMS) const KeyAddedCB& key_added_cb, const KeyErrorCB& key_error_cb, @@ -70,6 +69,12 @@ class ProxyDecryptor { // Decryptor is associated. media::Decryptor* GetDecryptor(); +#if defined(OS_ANDROID) + // Returns the CDM ID associated with this object. May be kInvalidCdmId if no + // CDM ID is associated, such as when Clear Key is used. + int GetCdmId(); +#endif + // Only call this once. bool InitializeCDM(const std::string& key_system, const GURL& frame_url); diff --git a/content/renderer/media/webcontentdecryptionmodule_impl.cc b/content/renderer/media/webcontentdecryptionmodule_impl.cc index a9b201fbc13278..206a7cc7017c57 100644 --- a/content/renderer/media/webcontentdecryptionmodule_impl.cc +++ b/content/renderer/media/webcontentdecryptionmodule_impl.cc @@ -44,6 +44,7 @@ WebContentDecryptionModuleImpl* WebContentDecryptionModuleImpl::Create( } scoped_refptr adapter(new CdmSessionAdapter()); + if (!adapter->Initialize( #if defined(ENABLE_PEPPER_CDMS) base::Bind(&PepperCdmWrapperImpl::Create, frame), @@ -57,8 +58,7 @@ WebContentDecryptionModuleImpl* WebContentDecryptionModuleImpl::Create( WebContentDecryptionModuleImpl::WebContentDecryptionModuleImpl( scoped_refptr adapter) - : adapter_(adapter) { -} + : adapter_(adapter) {} WebContentDecryptionModuleImpl::~WebContentDecryptionModuleImpl() { } @@ -74,4 +74,10 @@ media::Decryptor* WebContentDecryptionModuleImpl::GetDecryptor() { return adapter_->GetDecryptor(); } +#if defined(OS_ANDROID) +int WebContentDecryptionModuleImpl::GetCdmId() const { + return adapter_->GetCdmId(); +} +#endif // defined(OS_ANDROID) + } // namespace content diff --git a/content/renderer/media/webcontentdecryptionmodule_impl.h b/content/renderer/media/webcontentdecryptionmodule_impl.h index 3a07a24c9b7706..38df1a0d16d38b 100644 --- a/content/renderer/media/webcontentdecryptionmodule_impl.h +++ b/content/renderer/media/webcontentdecryptionmodule_impl.h @@ -43,6 +43,12 @@ class WebContentDecryptionModuleImpl // after WebContentDecryptionModule is freed. http://crbug.com/330324 media::Decryptor* GetDecryptor(); +#if defined(OS_ANDROID) + // Returns the CDM ID associated with this object. May be kInvalidCdmId if no + // CDM ID is associated, such as when Clear Key is used. + int GetCdmId() const; +#endif // defined(OS_ANDROID) + // blink::WebContentDecryptionModule implementation. virtual blink::WebContentDecryptionModuleSession* createSession( blink::WebContentDecryptionModuleSession::Client* client); diff --git a/content/renderer/media/webmediaplayer_impl.cc b/content/renderer/media/webmediaplayer_impl.cc index dbe3924d344550..711245bff6b437 100644 --- a/content/renderer/media/webmediaplayer_impl.cc +++ b/content/renderer/media/webmediaplayer_impl.cc @@ -1306,7 +1306,7 @@ void WebMediaPlayerImpl::SetDecryptorReadyCB( DCHECK(decryptor_ready_cb_.is_null()); // Mixed use of prefixed and unprefixed EME APIs is disallowed by Blink. - DCHECK(!(proxy_decryptor_ && web_cdm_)); + DCHECK(!proxy_decryptor_ || !web_cdm_); if (proxy_decryptor_) { decryptor_ready_cb.Run(proxy_decryptor_->GetDecryptor()); diff --git a/content/renderer/media/webmediaplayer_impl.h b/content/renderer/media/webmediaplayer_impl.h index cdbeae98809880..60d01387579bd2 100644 --- a/content/renderer/media/webmediaplayer_impl.h +++ b/content/renderer/media/webmediaplayer_impl.h @@ -17,6 +17,7 @@ #include "content/renderer/media/video_frame_compositor.h" #include "media/base/audio_renderer_sink.h" #include "media/base/decryptor.h" +// TODO(xhwang): Remove when we remove prefixed EME implementation. #include "media/base/media_keys.h" #include "media/base/pipeline.h" #include "media/base/text_track.h"