diff options
author | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-16 16:55:29 +0000 |
---|---|---|
committer | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-16 16:55:29 +0000 |
commit | 4f91fc49aff3fb7b72a94b1293836ed3a8a0361c (patch) | |
tree | c7e26f54b2a6956aa4ea778747ad718d8d7b5d34 /media | |
parent | 8ba705136f136c2091d767f3ba04159b42891b1b (diff) | |
download | chromium_src-4f91fc49aff3fb7b72a94b1293836ed3a8a0361c.zip chromium_src-4f91fc49aff3fb7b72a94b1293836ed3a8a0361c.tar.gz chromium_src-4f91fc49aff3fb7b72a94b1293836ed3a8a0361c.tar.bz2 |
BrowserMediaPlayerManager manages MediaKeys objects.
Changes in this CL:
- Add cdm_factory.h to support platform specific CDM creation.
- Detach BrowserMediaPlayerManager from MediaDrmBridge.
- Store the security origin of CDMs in the manager so that CDMs don't need to
know it.
- Keep the CDM ID in the manager so that CDMs don't see it.
BUG=338910
TEST=Test page plays and tests still pass.
Review URL: https://codereview.chromium.org/276973005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271034 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/base/android/cdm_factory_android.cc | 53 | ||||
-rw-r--r-- | media/base/android/media_drm_bridge.cc | 86 | ||||
-rw-r--r-- | media/base/android/media_drm_bridge.h | 45 | ||||
-rw-r--r-- | media/base/android/media_player_android.cc | 6 | ||||
-rw-r--r-- | media/base/android/media_player_android.h | 6 | ||||
-rw-r--r-- | media/base/android/media_player_manager.h | 18 | ||||
-rw-r--r-- | media/base/android/media_source_player.cc | 5 | ||||
-rw-r--r-- | media/base/android/media_source_player.h | 2 | ||||
-rw-r--r-- | media/base/android/media_source_player_unittest.cc | 4 | ||||
-rw-r--r-- | media/base/cdm_factory.h | 28 | ||||
-rw-r--r-- | media/base/media_keys.h | 1 | ||||
-rw-r--r-- | media/media.gyp | 2 |
12 files changed, 186 insertions, 70 deletions
diff --git a/media/base/android/cdm_factory_android.cc b/media/base/android/cdm_factory_android.cc new file mode 100644 index 0000000..c9b24e2 --- /dev/null +++ b/media/base/android/cdm_factory_android.cc @@ -0,0 +1,53 @@ +// 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. + +#include "media/base/cdm_factory.h" + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "media/base/android/media_drm_bridge.h" +#include "media/base/media_switches.h" + +namespace media { + +scoped_ptr<MediaKeys> CreateBrowserCdm( + const std::string& key_system, + const SessionCreatedCB& session_created_cb, + const SessionMessageCB& session_message_cb, + const SessionReadyCB& session_ready_cb, + const SessionClosedCB& session_closed_cb, + const SessionErrorCB& session_error_cb) { + if (!MediaDrmBridge::IsKeySystemSupported(key_system)) { + NOTREACHED() << "Unsupported key system: " << key_system; + return scoped_ptr<MediaKeys>(); + } + + scoped_ptr<MediaDrmBridge> cdm(MediaDrmBridge::Create(key_system, + session_created_cb, + session_message_cb, + session_ready_cb, + session_closed_cb, + session_error_cb)); + if (!cdm) { + NOTREACHED() << "MediaDrmBridge cannot be created for " << key_system; + return scoped_ptr<MediaKeys>(); + } + + // TODO(xhwang/ddorwin): Pass the security level from key system. + MediaDrmBridge::SecurityLevel security_level = + MediaDrmBridge::SECURITY_LEVEL_3; + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kMediaDrmEnableNonCompositing)) { + security_level = MediaDrmBridge::SECURITY_LEVEL_1; + } + if (!cdm->SetSecurityLevel(security_level)) { + DVLOG(1) << "failed to set security level " << security_level; + return scoped_ptr<MediaKeys>(); + } + + return cdm.PassAs<MediaKeys>(); +} + +} // namespace media diff --git a/media/base/android/media_drm_bridge.cc b/media/base/android/media_drm_bridge.cc index dbcd187..b627259 100644 --- a/media/base/android/media_drm_bridge.cc +++ b/media/base/android/media_drm_bridge.cc @@ -15,7 +15,6 @@ #include "base/message_loop/message_loop_proxy.h" #include "base/strings/string_util.h" #include "jni/MediaDrmBridge_jni.h" -#include "media/base/android/media_player_manager.h" #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. @@ -223,10 +222,8 @@ bool MediaDrmBridge::IsSecurityLevelSupported(const std::string& key_system, if (!IsAvailable()) return false; - // Pass 0 as |cdm_id| and NULL as |manager| as they are not used in - // creation time of MediaDrmBridge. scoped_ptr<MediaDrmBridge> media_drm_bridge = - MediaDrmBridge::Create(0, key_system, GURL(), NULL); + MediaDrmBridge::CreateSessionless(key_system); if (!media_drm_bridge) return false; @@ -251,14 +248,18 @@ bool MediaDrmBridge::RegisterMediaDrmBridge(JNIEnv* env) { return RegisterNativesImpl(env); } -MediaDrmBridge::MediaDrmBridge(int cdm_id, - const std::vector<uint8>& scheme_uuid, - const GURL& security_origin, - MediaPlayerManager* manager) - : cdm_id_(cdm_id), - scheme_uuid_(scheme_uuid), - security_origin_(security_origin), - manager_(manager) { +MediaDrmBridge::MediaDrmBridge(const std::vector<uint8>& scheme_uuid, + const SessionCreatedCB& session_created_cb, + const SessionMessageCB& session_message_cb, + const SessionReadyCB& session_ready_cb, + const SessionClosedCB& session_closed_cb, + const SessionErrorCB& session_error_cb) + : scheme_uuid_(scheme_uuid), + 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) { JNIEnv* env = AttachCurrentThread(); CHECK(env); @@ -275,10 +276,13 @@ MediaDrmBridge::~MediaDrmBridge() { } // static -scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create(int cdm_id, - const std::string& key_system, - const GURL& security_origin, - MediaPlayerManager* manager) { +scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create( + const std::string& key_system, + const SessionCreatedCB& session_created_cb, + const SessionMessageCB& session_message_cb, + const SessionReadyCB& session_ready_cb, + const SessionClosedCB& session_closed_cb, + const SessionErrorCB& session_error_cb) { scoped_ptr<MediaDrmBridge> media_drm_bridge; if (!IsAvailable()) return media_drm_bridge.Pass(); @@ -287,14 +291,30 @@ scoped_ptr<MediaDrmBridge> MediaDrmBridge::Create(int cdm_id, if (scheme_uuid.empty()) return media_drm_bridge.Pass(); - media_drm_bridge.reset( - new MediaDrmBridge(cdm_id, scheme_uuid, security_origin, manager)); + media_drm_bridge.reset(new MediaDrmBridge(scheme_uuid, + session_created_cb, + session_message_cb, + session_ready_cb, + session_closed_cb, + session_error_cb)); + if (media_drm_bridge->j_media_drm_.is_null()) media_drm_bridge.reset(); return media_drm_bridge.Pass(); } +// static +scoped_ptr<MediaDrmBridge> MediaDrmBridge::CreateSessionless( + const std::string& key_system) { + return MediaDrmBridge::Create(key_system, + SessionCreatedCB(), + SessionMessageCB(), + SessionReadyCB(), + SessionClosedCB(), + SessionErrorCB()); +} + bool MediaDrmBridge::SetSecurityLevel(SecurityLevel security_level) { JNIEnv* env = AttachCurrentThread(); @@ -312,6 +332,11 @@ bool MediaDrmBridge::CreateSession(uint32 session_id, const std::string& content_type, const uint8* init_data, int init_data_length) { + DVLOG(1) << __FUNCTION__; + + DCHECK(!session_created_cb_.is_null()) + << "CreateSession called on a sessionless MediaDrmBridge object."; + JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jbyteArray> j_init_data; // Caller should always use "video/*" content types. @@ -348,6 +373,10 @@ void MediaDrmBridge::UpdateSession(uint32 session_id, const uint8* response, int response_length) { DVLOG(1) << __FUNCTION__; + + DCHECK(!session_ready_cb_.is_null()) + << __FUNCTION__ << " called on a sessionless MediaDrmBridge object."; + JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jbyteArray> j_response = base::android::ToJavaByteArray(env, response, response_length); @@ -357,6 +386,10 @@ void MediaDrmBridge::UpdateSession(uint32 session_id, void MediaDrmBridge::ReleaseSession(uint32 session_id) { DVLOG(1) << __FUNCTION__; + + DCHECK(!session_closed_cb_.is_null()) + << __FUNCTION__ << " called on a sessionless MediaDrmBridge object."; + JNIEnv* env = AttachCurrentThread(); Java_MediaDrmBridge_releaseSession(env, j_media_drm_.obj(), session_id); } @@ -389,7 +422,7 @@ void MediaDrmBridge::OnSessionCreated(JNIEnv* env, jstring j_web_session_id) { uint32 session_id = j_session_id; std::string web_session_id = ConvertJavaStringToUTF8(env, j_web_session_id); - manager_->OnSessionCreated(cdm_id_, session_id, web_session_id); + session_created_cb_.Run(session_id, web_session_id); } void MediaDrmBridge::OnSessionMessage(JNIEnv* env, @@ -401,35 +434,28 @@ void MediaDrmBridge::OnSessionMessage(JNIEnv* env, std::vector<uint8> message; JavaByteArrayToByteVector(env, j_message, &message); std::string destination_url = ConvertJavaStringToUTF8(env, j_destination_url); - GURL destination_gurl(destination_url); - if (!destination_gurl.is_valid() && !destination_gurl.is_empty()) { - DLOG(WARNING) << "SessionMessage destination_url is invalid : " - << destination_gurl.possibly_invalid_spec(); - destination_gurl = GURL::EmptyGURL(); // Replace invalid destination_url. - } - - manager_->OnSessionMessage(cdm_id_, session_id, message, destination_gurl); + session_message_cb_.Run(session_id, message, destination_url); } void MediaDrmBridge::OnSessionReady(JNIEnv* env, jobject j_media_drm, jint j_session_id) { uint32 session_id = j_session_id; - manager_->OnSessionReady(cdm_id_, session_id); + session_ready_cb_.Run(session_id); } void MediaDrmBridge::OnSessionClosed(JNIEnv* env, jobject j_media_drm, jint j_session_id) { uint32 session_id = j_session_id; - manager_->OnSessionClosed(cdm_id_, session_id); + session_closed_cb_.Run(session_id); } void MediaDrmBridge::OnSessionError(JNIEnv* env, jobject j_media_drm, jint j_session_id) { uint32 session_id = j_session_id; - manager_->OnSessionError(cdm_id_, session_id, MediaKeys::kUnknownError, 0); + session_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); } ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { diff --git a/media/base/android/media_drm_bridge.h b/media/base/android/media_drm_bridge.h index f34bbc4..60b4dd8 100644 --- a/media/base/android/media_drm_bridge.h +++ b/media/base/android/media_drm_bridge.h @@ -59,10 +59,19 @@ class MEDIA_EXPORT MediaDrmBridge : public MediaKeys { // Returns a MediaDrmBridge instance if |key_system| is supported, or a NULL // pointer otherwise. - static scoped_ptr<MediaDrmBridge> Create(int cdm_id, - const std::string& key_system, - const GURL& security_origin, - MediaPlayerManager* manager); + static scoped_ptr<MediaDrmBridge> Create( + const std::string& key_system, + const SessionCreatedCB& session_created_cb, + const SessionMessageCB& session_message_cb, + const SessionReadyCB& session_ready_cb, + const SessionClosedCB& session_closed_cb, + const SessionErrorCB& session_error_cb); + + // Returns a MediaDrmBridge instance if |key_system| is supported, or a NULL + // otherwise. No session callbacks are provided. This is used when we need to + // use MediaDrmBridge without creating any sessions. + static scoped_ptr<MediaDrmBridge> CreateSessionless( + const std::string& key_system); // Returns true if |security_level| is successfully set, or false otherwise. // Call this function right after Create() and before any other calls. @@ -120,33 +129,29 @@ class MEDIA_EXPORT MediaDrmBridge : public MediaKeys { // video playback. bool IsProtectedSurfaceRequired(); - int cdm_id() const { return cdm_id_; } - - const GURL& security_origin() const { return security_origin_; } - private: - MediaDrmBridge(int cdm_id, - const std::vector<uint8>& scheme_uuid, - const GURL& security_origin, - MediaPlayerManager* manager); + MediaDrmBridge(const std::vector<uint8>& scheme_uuid, + const SessionCreatedCB& session_created_cb, + const SessionMessageCB& session_message_cb, + const SessionReadyCB& session_ready_cb, + const SessionClosedCB& session_closed_cb, + const SessionErrorCB& session_error_cb); // Get the security level of the media. SecurityLevel GetSecurityLevel(); - // ID of the CDM object. - int cdm_id_; - // UUID of the key system. std::vector<uint8> scheme_uuid_; - // media stream's security origin. - const GURL security_origin_; - // Java MediaDrm instance. base::android::ScopedJavaGlobalRef<jobject> j_media_drm_; - // Non-owned pointer. - MediaPlayerManager* manager_; + // Callbacks for firing session events. + SessionCreatedCB session_created_cb_; + SessionMessageCB session_message_cb_; + SessionReadyCB session_ready_cb_; + SessionClosedCB session_closed_cb_; + SessionErrorCB session_error_cb_; base::Closure media_crypto_ready_cb_; diff --git a/media/base/android/media_player_android.cc b/media/base/android/media_player_android.cc index 39696527..158e520 100644 --- a/media/base/android/media_player_android.cc +++ b/media/base/android/media_player_android.cc @@ -5,8 +5,8 @@ #include "media/base/android/media_player_android.h" #include "base/logging.h" -#include "media/base/android/media_drm_bridge.h" #include "media/base/android/media_player_manager.h" +#include "media/base/media_keys.h" namespace media { @@ -31,8 +31,8 @@ GURL MediaPlayerAndroid::GetFirstPartyForCookies() { return GURL(); } -void MediaPlayerAndroid::SetDrmBridge(MediaDrmBridge* drm_bridge) { - // Not all players support DrmBridge. Do nothing by default. +void MediaPlayerAndroid::SetCdm(MediaKeys* cdm) { + // Not all players support CDMs. Do nothing by default. return; } diff --git a/media/base/android/media_player_android.h b/media/base/android/media_player_android.h index 0fd4815..cf67bd0 100644 --- a/media/base/android/media_player_android.h +++ b/media/base/android/media_player_android.h @@ -16,7 +16,7 @@ namespace media { -class MediaDrmBridge; +class MediaKeys; class MediaPlayerManager; // This class serves as the base class for different media player @@ -73,8 +73,8 @@ class MEDIA_EXPORT MediaPlayerAndroid { virtual GURL GetUrl(); virtual GURL GetFirstPartyForCookies(); - // Pass a drm bridge to a player. - virtual void SetDrmBridge(MediaDrmBridge* drm_bridge); + // Associates the |cdm| with this player. + virtual void SetCdm(MediaKeys* cdm); // Notifies the player that a decryption key has been added. The player // may want to start/resume playback if it is waiting for a key. diff --git a/media/base/android/media_player_manager.h b/media/base/android/media_player_manager.h index 50132c3..4666fb5 100644 --- a/media/base/android/media_player_manager.h +++ b/media/base/android/media_player_manager.h @@ -16,7 +16,7 @@ namespace media { -class MediaDrmBridge; +class MediaKeys; class MediaPlayerAndroid; class MediaResourceGetter; @@ -71,8 +71,8 @@ class MEDIA_EXPORT MediaPlayerManager { // Release all the players managed by this object. virtual void DestroyAllMediaPlayers() = 0; - // Get the MediaDrmBridge object for the given media key Id. - virtual media::MediaDrmBridge* GetDrmBridge(int cdm_id) = 0; + // Get the CDM for the given CDM ID. + virtual MediaKeys* GetCdm(int cdm_id) = 0; // Called by the player to get a hardware protected surface. virtual void RequestFullScreen(int player_id) = 0; @@ -82,24 +82,24 @@ class MEDIA_EXPORT MediaPlayerManager { // to support the W3C Working Draft version of the EME spec. // http://crbug.com/315312 - // Called when MediaDrmBridge determines a SessionId. + // Called when CDM creates a session. virtual void OnSessionCreated(int cdm_id, uint32 session_id, const std::string& web_session_id) = 0; - // Called when MediaDrmBridge wants to send a Message event. + // Called when CDM wants to send a Message event. virtual void OnSessionMessage(int cdm_id, uint32 session_id, const std::vector<uint8>& message, - const GURL& destination_url) = 0; + const std::string& destination_url) = 0; - // Called when MediaDrmBridge wants to send a Ready event. + // Called when CDM wants to send a Ready event. virtual void OnSessionReady(int cdm_id, uint32 session_id) = 0; - // Called when MediaDrmBridge wants to send a Closed event. + // Called when CDM wants to send a Closed event. virtual void OnSessionClosed(int cdm_id, uint32 session_id) = 0; - // Called when MediaDrmBridge wants to send an Error event. + // Called when CDM wants to send an Error event. virtual void OnSessionError(int cdm_id, uint32 session_id, media::MediaKeys::KeyError error_code, diff --git a/media/base/android/media_source_player.cc b/media/base/android/media_source_player.cc index 42023c4..081d691 100644 --- a/media/base/android/media_source_player.cc +++ b/media/base/android/media_source_player.cc @@ -355,7 +355,7 @@ void MediaSourcePlayer::OnMediaCryptoReady() { StartInternal(); } -void MediaSourcePlayer::SetDrmBridge(MediaDrmBridge* drm_bridge) { +void MediaSourcePlayer::SetCdm(MediaKeys* cdm) { // Currently we don't support DRM change during the middle of playback, even // if the player is paused. // TODO(qinmin): support DRM change after playback has started. @@ -365,7 +365,8 @@ void MediaSourcePlayer::SetDrmBridge(MediaDrmBridge* drm_bridge) { << "This is not well supported!"; } - drm_bridge_ = drm_bridge; + // Only MediaDrmBridge will be set on MediaSourcePlayer. + drm_bridge_ = static_cast<MediaDrmBridge*>(cdm); if (drm_bridge_->GetMediaCrypto().is_null()) { drm_bridge_->SetMediaCryptoReadyCB(base::Bind( diff --git a/media/base/android/media_source_player.h b/media/base/android/media_source_player.h index 6681381..6389ec1 100644 --- a/media/base/android/media_source_player.h +++ b/media/base/android/media_source_player.h @@ -61,7 +61,7 @@ class MEDIA_EXPORT MediaSourcePlayer : public MediaPlayerAndroid, virtual bool CanSeekForward() OVERRIDE; virtual bool CanSeekBackward() OVERRIDE; virtual bool IsPlayerReady() OVERRIDE; - virtual void SetDrmBridge(MediaDrmBridge* drm_bridge) OVERRIDE; + virtual void SetCdm(MediaKeys* cdm) OVERRIDE; virtual void OnKeyAdded() OVERRIDE; virtual bool IsSurfaceInUse() const OVERRIDE; diff --git a/media/base/android/media_source_player_unittest.cc b/media/base/android/media_source_player_unittest.cc index ed861a2..546ffc0 100644 --- a/media/base/android/media_source_player_unittest.cc +++ b/media/base/android/media_source_player_unittest.cc @@ -72,7 +72,7 @@ class MockMediaPlayerManager : public MediaPlayerManager { virtual MediaPlayerAndroid* GetFullscreenPlayer() OVERRIDE { return NULL; } virtual MediaPlayerAndroid* GetPlayer(int player_id) OVERRIDE { return NULL; } virtual void DestroyAllMediaPlayers() OVERRIDE {} - virtual MediaDrmBridge* GetDrmBridge(int cdm_id) OVERRIDE { return NULL; } + virtual MediaKeys* GetCdm(int cdm_id) OVERRIDE { return NULL; } virtual void RequestFullScreen(int player_id) OVERRIDE {} virtual void OnSessionCreated(int cdm_id, uint32 session_id, @@ -80,7 +80,7 @@ class MockMediaPlayerManager : public MediaPlayerManager { virtual void OnSessionMessage(int cdm_id, uint32 session_id, const std::vector<uint8>& message, - const GURL& destination_url) OVERRIDE {} + const std::string& destination_url) OVERRIDE {} virtual void OnSessionReady(int cdm_id, uint32 session_id) OVERRIDE {} virtual void OnSessionClosed(int cdm_id, uint32 session_id) OVERRIDE {} virtual void OnSessionError(int cdm_id, diff --git a/media/base/cdm_factory.h b/media/base/cdm_factory.h new file mode 100644 index 0000000..ccdefa7 --- /dev/null +++ b/media/base/cdm_factory.h @@ -0,0 +1,28 @@ +// 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 MEDIA_BASE_CDM_FACTORY_H_ +#define MEDIA_BASE_CDM_FACTORY_H_ + +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "media/base/media_export.h" +#include "media/base/media_keys.h" + +namespace media { + +// Creates a CDM for |key_system|. Returns NULL if the CDM cannot be created. +// TODO(xhwang): Add ifdef for IPC based CDM. +scoped_ptr<MediaKeys> MEDIA_EXPORT + CreateBrowserCdm(const std::string& key_system, + const SessionCreatedCB& session_created_cb, + const SessionMessageCB& session_message_cb, + const SessionReadyCB& session_ready_cb, + const SessionClosedCB& session_closed_cb, + const SessionErrorCB& session_error_cb); + +} // namespace media + +#endif // MEDIA_BASE_CDM_FACTORY_H_ diff --git a/media/base/media_keys.h b/media/base/media_keys.h index a6ef64ce..4af3581 100644 --- a/media/base/media_keys.h +++ b/media/base/media_keys.h @@ -82,6 +82,7 @@ typedef base::Callback< void(uint32 session_id, const std::string& web_session_id)> SessionCreatedCB; +// TODO(xhwang): Use GURL for |destination_url|. See http://crbug.com/372877 typedef base::Callback<void(uint32 session_id, const std::vector<uint8>& message, const std::string& destination_url)> diff --git a/media/media.gyp b/media/media.gyp index db56ca8..c108335 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -1615,6 +1615,7 @@ 'sources': [ 'base/android/audio_decoder_job.cc', 'base/android/audio_decoder_job.h', + 'base/android/cdm_factory_android.cc', 'base/android/media_codec_bridge.cc', 'base/android/media_codec_bridge.h', 'base/android/media_decoder_job.cc', @@ -1636,6 +1637,7 @@ 'base/android/webaudio_media_codec_bridge.cc', 'base/android/webaudio_media_codec_bridge.h', 'base/android/webaudio_media_codec_info.h', + 'base/cdm_factory.h', ], 'dependencies': [ '../base/base.gyp:base', |