summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-16 16:55:29 +0000
committerxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-16 16:55:29 +0000
commit4f91fc49aff3fb7b72a94b1293836ed3a8a0361c (patch)
treec7e26f54b2a6956aa4ea778747ad718d8d7b5d34 /content
parent8ba705136f136c2091d767f3ba04159b42891b1b (diff)
downloadchromium_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 'content')
-rw-r--r--content/browser/media/android/browser_media_player_manager.cc180
-rw-r--r--content/browser/media/android/browser_media_player_manager.h48
-rw-r--r--content/browser/media/android/media_drm_credential_manager.cc2
3 files changed, 125 insertions, 105 deletions
diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc
index b4a71e8..ac37e42 100644
--- a/content/browser/media/android/browser_media_player_manager.cc
+++ b/content/browser/media/android/browser_media_player_manager.cc
@@ -6,6 +6,7 @@
#include "base/android/scoped_java_ref.h"
#include "base/command_line.h"
+#include "base/stl_util.h"
#include "content/browser/android/content_view_core_impl.h"
#include "content/browser/media/android/browser_demuxer_android.h"
#include "content/browser/media/android/media_resource_getter_impl.h"
@@ -24,12 +25,12 @@
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
-#include "media/base/android/media_drm_bridge.h"
#include "media/base/android/media_player_bridge.h"
#include "media/base/android/media_source_player.h"
+#include "media/base/cdm_factory.h"
#include "media/base/media_switches.h"
-using media::MediaDrmBridge;
+using media::MediaKeys;
using media::MediaPlayerAndroid;
using media::MediaPlayerBridge;
using media::MediaPlayerManager;
@@ -342,18 +343,14 @@ MediaPlayerAndroid* BrowserMediaPlayerManager::GetPlayer(int player_id) {
return NULL;
}
-MediaDrmBridge* BrowserMediaPlayerManager::GetDrmBridge(int cdm_id) {
- for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin();
- it != drm_bridges_.end(); ++it) {
- if ((*it)->cdm_id() == cdm_id)
- return *it;
- }
- return NULL;
+MediaKeys* BrowserMediaPlayerManager::GetCdm(int cdm_id) {
+ CdmMap::const_iterator iter = cdm_map_.find(cdm_id);
+ return (iter == cdm_map_.end()) ? NULL : iter->second;
}
void BrowserMediaPlayerManager::DestroyAllMediaPlayers() {
players_.clear();
- drm_bridges_.clear();
+ STLDeleteValues(&cdm_map_);
if (fullscreen_player_id_ != -1) {
video_view_.reset();
fullscreen_player_id_ = -1;
@@ -394,9 +391,16 @@ void BrowserMediaPlayerManager::OnSessionMessage(
int cdm_id,
uint32 session_id,
const std::vector<uint8>& message,
- const GURL& destination_url) {
+ const std::string& 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.
+ }
+
Send(new CdmMsg_SessionMessage(
- routing_id(), cdm_id, session_id, message, destination_url));
+ routing_id(), cdm_id, session_id, message, destination_gurl));
}
void BrowserMediaPlayerManager::OnSessionReady(int cdm_id, uint32 session_id) {
@@ -591,17 +595,12 @@ void BrowserMediaPlayerManager::OnInitializeCdm(int cdm_id,
const GURL& security_origin) {
if (key_system.size() > kMaxKeySystemLength) {
// This failure will be discovered and reported by OnCreateSession()
- // as GetDrmBridge() will return null.
+ // as GetCdm() will return null.
NOTREACHED() << "Invalid key system: " << key_system;
return;
}
- if (!MediaDrmBridge::IsKeySystemSupported(key_system)) {
- NOTREACHED() << "Unsupported key system: " << key_system;
- return;
- }
-
- AddDrmBridge(cdm_id, key_system, security_origin);
+ AddCdm(cdm_id, key_system, security_origin);
}
void BrowserMediaPlayerManager::OnCreateSession(
@@ -639,9 +638,9 @@ void BrowserMediaPlayerManager::OnCreateSession(
return;
}
- MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id);
- if (!drm_bridge) {
- DLOG(WARNING) << "No MediaDrmBridge for ID: " << cdm_id << " found";
+ MediaKeys* cdm = GetCdm(cdm_id);
+ if (!cdm) {
+ DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0);
return;
}
@@ -649,12 +648,20 @@ void BrowserMediaPlayerManager::OnCreateSession(
BrowserContext* context =
web_contents()->GetRenderProcessHost()->GetBrowserContext();
+ std::map<int, GURL>::const_iterator iter =
+ cdm_security_origin_map_.find(cdm_id);
+ if (iter == cdm_security_origin_map_.end()) {
+ NOTREACHED();
+ OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0);
+ return;
+ }
+
context->RequestProtectedMediaIdentifierPermission(
web_contents()->GetRenderProcessHost()->GetID(),
web_contents()->GetRenderViewHost()->GetRoutingID(),
static_cast<int>(session_id),
cdm_id,
- drm_bridge->security_origin(),
+ iter->second,
base::Bind(&BrowserMediaPlayerManager::CreateSessionIfPermitted,
weak_ptr_factory_.GetWeakPtr(),
cdm_id,
@@ -667,24 +674,24 @@ void BrowserMediaPlayerManager::OnUpdateSession(
int cdm_id,
uint32 session_id,
const std::vector<uint8>& response) {
- MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id);
- if (!drm_bridge) {
- DLOG(WARNING) << "No MediaDrmBridge for ID: " << cdm_id << " found";
+ MediaKeys* cdm = GetCdm(cdm_id);
+ if (!cdm) {
+ DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0);
return;
}
if (response.size() > kMaxSessionResponseLength) {
- LOG(WARNING) << "Response for ID: " << cdm_id
- << " too long: " << response.size();
+ LOG(WARNING) << "Response for ID " << cdm_id
+ << " is too long: " << response.size();
OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0);
return;
}
- drm_bridge->UpdateSession(session_id, &response[0], response.size());
+ cdm->UpdateSession(session_id, &response[0], response.size());
- DrmBridgePlayerMap::const_iterator iter = drm_bridge_player_map_.find(cdm_id);
- if (iter == drm_bridge_player_map_.end())
+ CdmToPlayerMap::const_iterator iter = cdm_to_player_map_.find(cdm_id);
+ if (iter == cdm_to_player_map_.end())
return;
int player_id = iter->second;
@@ -695,22 +702,23 @@ void BrowserMediaPlayerManager::OnUpdateSession(
void BrowserMediaPlayerManager::OnReleaseSession(int cdm_id,
uint32 session_id) {
- MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id);
- if (!drm_bridge) {
- DLOG(WARNING) << "No MediaDrmBridge for ID: " << cdm_id << " found";
+ MediaKeys* cdm = GetCdm(cdm_id);
+ if (!cdm) {
+ DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0);
return;
}
- drm_bridge->ReleaseSession(session_id);
+ cdm->ReleaseSession(session_id);
}
void BrowserMediaPlayerManager::OnDestroyCdm(int cdm_id) {
- MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id);
- if (!drm_bridge) return;
+ MediaKeys* cdm = GetCdm(cdm_id);
+ if (!cdm)
+ return;
CancelAllPendingSessionCreations(cdm_id);
- RemoveDrmBridge(cdm_id);
+ RemoveCdm(cdm_id);
}
void BrowserMediaPlayerManager::CancelAllPendingSessionCreations(int cdm_id) {
@@ -734,10 +742,11 @@ void BrowserMediaPlayerManager::RemovePlayer(int player_id) {
}
}
- for (DrmBridgePlayerMap::iterator it = drm_bridge_player_map_.begin();
- it != drm_bridge_player_map_.end(); ++it) {
+ for (CdmToPlayerMap::iterator it = cdm_to_player_map_.begin();
+ it != cdm_to_player_map_.end();
+ ++it) {
if (it->second == player_id) {
- drm_bridge_player_map_.erase(it);
+ cdm_to_player_map_.erase(it);
break;
}
}
@@ -758,64 +767,70 @@ scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer(
return scoped_ptr<media::MediaPlayerAndroid>(previous_player);
}
-void BrowserMediaPlayerManager::AddDrmBridge(int cdm_id,
- const std::string& key_system,
- const GURL& security_origin) {
- DCHECK(!GetDrmBridge(cdm_id));
-
- scoped_ptr<MediaDrmBridge> drm_bridge(
- MediaDrmBridge::Create(cdm_id, key_system, security_origin, this));
- if (!drm_bridge) {
+void BrowserMediaPlayerManager::AddCdm(int cdm_id,
+ const std::string& key_system,
+ const GURL& security_origin) {
+ DCHECK(!GetCdm(cdm_id));
+ base::WeakPtr<BrowserMediaPlayerManager> weak_this =
+ weak_ptr_factory_.GetWeakPtr();
+
+ scoped_ptr<MediaKeys> cdm(media::CreateBrowserCdm(
+ key_system,
+ base::Bind(
+ &BrowserMediaPlayerManager::OnSessionCreated, weak_this, cdm_id),
+ base::Bind(
+ &BrowserMediaPlayerManager::OnSessionMessage, weak_this, cdm_id),
+ base::Bind(
+ &BrowserMediaPlayerManager::OnSessionReady, weak_this, cdm_id),
+ base::Bind(
+ &BrowserMediaPlayerManager::OnSessionClosed, weak_this, cdm_id),
+ base::Bind(
+ &BrowserMediaPlayerManager::OnSessionError, weak_this, cdm_id)));
+
+ if (!cdm) {
// This failure will be discovered and reported by OnCreateSession()
- // as GetDrmBridge() will return null.
- DVLOG(1) << "failed to create drm bridge.";
- return;
- }
-
- // 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 (!drm_bridge->SetSecurityLevel(security_level)) {
- DVLOG(1) << "failed to set security level " << security_level;
+ // as GetCdm() will return null.
+ DVLOG(1) << "failed to create CDM.";
return;
}
- drm_bridges_.push_back(drm_bridge.release());
+ cdm_map_[cdm_id] = cdm.release();
+ cdm_security_origin_map_[cdm_id] = security_origin;
}
-void BrowserMediaPlayerManager::RemoveDrmBridge(int cdm_id) {
- // TODO(xhwang): Detach DrmBridge from the player it's set to. In prefixed
+void BrowserMediaPlayerManager::RemoveCdm(int cdm_id) {
+ // TODO(xhwang): Detach CDM from the player it's set to. In prefixed
// EME implementation the current code is fine because we always destroy the
// player before we destroy the DrmBridge. This will not always be the case
// in unprefixed EME implementation.
- for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin();
- it != drm_bridges_.end(); ++it) {
- if ((*it)->cdm_id() == cdm_id) {
- drm_bridges_.erase(it);
- drm_bridge_player_map_.erase(cdm_id);
- break;
- }
+ CdmMap::iterator iter = cdm_map_.find(cdm_id);
+ if (iter != cdm_map_.end()) {
+ delete iter->second;
+ cdm_map_.erase(iter);
}
+ cdm_to_player_map_.erase(cdm_id);
+ cdm_security_origin_map_.erase(cdm_id);
}
void BrowserMediaPlayerManager::OnSetCdm(int player_id, int cdm_id) {
MediaPlayerAndroid* player = GetPlayer(player_id);
- MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id);
- if (!drm_bridge || !player) {
+ MediaKeys* cdm = GetCdm(cdm_id);
+ if (!cdm || !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);
+ player->SetCdm(cdm);
// Do now support setting one CDM on multiple players.
- DCHECK(drm_bridge_player_map_.find(cdm_id) == drm_bridge_player_map_.end());
- drm_bridge_player_map_[cdm_id] = player_id;
+
+ if (ContainsKey(cdm_to_player_map_, cdm_id)) {
+ DVLOG(1) << "CDM is already set on another player.";
+ return;
+ }
+
+ cdm_to_player_map_[cdm_id] = player_id;
}
void BrowserMediaPlayerManager::CreateSessionIfPermitted(
@@ -829,16 +844,15 @@ void BrowserMediaPlayerManager::CreateSessionIfPermitted(
return;
}
- MediaDrmBridge* drm_bridge = GetDrmBridge(cdm_id);
- if (!drm_bridge) {
- DLOG(WARNING) << "No MediaDrmBridge for ID: " << cdm_id << " found";
+ MediaKeys* cdm = GetCdm(cdm_id);
+ if (!cdm) {
+ DLOG(WARNING) << "No CDM for ID: " << cdm_id << " found";
OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0);
return;
}
// This could fail, in which case a SessionError will be fired.
- drm_bridge->CreateSession(
- session_id, content_type, &init_data[0], init_data.size());
+ cdm->CreateSession(session_id, content_type, &init_data[0], init_data.size());
}
void BrowserMediaPlayerManager::ReleaseFullscreenPlayer(
diff --git a/content/browser/media/android/browser_media_player_manager.h b/content/browser/media/android/browser_media_player_manager.h
index 308ed02..b6648f0 100644
--- a/content/browser/media/android/browser_media_player_manager.h
+++ b/content/browser/media/android/browser_media_player_manager.h
@@ -26,7 +26,7 @@
namespace media {
class DemuxerAndroid;
-class MediaDrmBridge;
+class MediaKeys;
}
namespace content {
@@ -35,11 +35,11 @@ class ContentViewCoreImpl;
class ExternalVideoSurfaceContainer;
class WebContents;
-// This class manages all the MediaPlayerAndroid objects. It receives
-// control operations from the the render process, and forwards
-// them to corresponding MediaPlayerAndroid object. Callbacks from
-// MediaPlayerAndroid objects are converted to IPCs and then sent to the
-// render process.
+// This class manages all the MediaPlayerAndroid and CDM objects.
+// It receives control operations from the the render process, and forwards
+// them to corresponding MediaPlayerAndroid or CDM object. Callbacks from
+// MediaPlayerAndroid and CDM objects are converted to IPCs and then sent to
+// the render process.
class CONTENT_EXPORT BrowserMediaPlayerManager
: public WebContentsObserver,
public media::MediaPlayerManager {
@@ -90,7 +90,7 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
virtual media::MediaResourceGetter* GetMediaResourceGetter() OVERRIDE;
virtual media::MediaPlayerAndroid* GetFullscreenPlayer() OVERRIDE;
virtual media::MediaPlayerAndroid* GetPlayer(int player_id) OVERRIDE;
- virtual media::MediaDrmBridge* GetDrmBridge(int cdm_id) OVERRIDE;
+ virtual media::MediaKeys* GetCdm(int cdm_id) OVERRIDE;
virtual void DestroyAllMediaPlayers() OVERRIDE;
virtual void RequestFullScreen(int player_id) OVERRIDE;
virtual void OnSessionCreated(int cdm_id,
@@ -99,7 +99,7 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
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,
@@ -164,14 +164,14 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
int player_id,
media::MediaPlayerAndroid* player);
- // Adds a new MediaDrmBridge for the given |key_system|, |cdm_id|, and
- // |frame_url|.
- void AddDrmBridge(int cdm_id,
- const std::string& key_system,
- const GURL& frame_url);
+ // Adds a new CDM identified by |cdm_id| for the given |key_system| and
+ // |security_origin|.
+ void AddCdm(int cdm_id,
+ const std::string& key_system,
+ const GURL& security_origin);
- // Removes the DRM bridge with the specified id.
- void RemoveDrmBridge(int cdm_id);
+ // Removes the CDM with the specified id.
+ void RemoveCdm(int cdm_id);
private:
// If |permitted| is false, it does nothing but send
@@ -216,13 +216,19 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
// An array of managed players.
ScopedVector<media::MediaPlayerAndroid> players_;
- // An array of managed media DRM bridges.
- ScopedVector<media::MediaDrmBridge> drm_bridges_;
+ // A map from CDM IDs to managed CDMs.
+ typedef std::map<int, media::MediaKeys*> CdmMap;
+ CdmMap cdm_map_;
- // Map from DrmBridge cdm_id to MediaPlayerAndroid player_id to indicate that
- // the DrmBridge is set on the MediaPlayerAndroid object.
- typedef std::map<int, int> DrmBridgePlayerMap;
- DrmBridgePlayerMap drm_bridge_player_map_;
+ // Map from CDM ID to MediaPlayerAndroid player ID to indicate that
+ // the CDM is set on the MediaPlayerAndroid object.
+ // TODO(xhwang): Register a callback in the CDM to resume playback so that we
+ // can remove this map. See http://crbug.com/373327
+ typedef std::map<int, int> CdmToPlayerMap;
+ CdmToPlayerMap cdm_to_player_map_;
+
+ // Map from CDM ID to CDM's security origin.
+ std::map<int, GURL> cdm_security_origin_map_;
// The fullscreen video view object or NULL if video is not played in
// fullscreen.
diff --git a/content/browser/media/android/media_drm_credential_manager.cc b/content/browser/media/android/media_drm_credential_manager.cc
index 0fb8618..23c6cf2 100644
--- a/content/browser/media/android/media_drm_credential_manager.cc
+++ b/content/browser/media/android/media_drm_credential_manager.cc
@@ -90,7 +90,7 @@ void MediaDrmCredentialManager::OnResetCredentialsCompleted(
bool MediaDrmCredentialManager::ResetCredentialsInternal(
SecurityLevel security_level) {
media_drm_bridge_ =
- media::MediaDrmBridge::Create(0, kWidevineKeySystem, GURL(), NULL);
+ media::MediaDrmBridge::CreateSessionless(kWidevineKeySystem);
if (!media_drm_bridge_)
return false;