Commit 8fc0f5be authored by xhwang@chromium.org's avatar xhwang@chromium.org

Separate BrowserCdmManager from BrowserMediaPlayerManager.

BUG=315312
TEST=Test pages still work.

Review URL: https://codereview.chromium.org/315733003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@275695 0039d316-1c4b-4281-b951-d872f2087c98
parent 03406ba7
// 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 "content/browser/media/android/browser_cdm_manager.h"
#include "base/command_line.h"
#include "base/stl_util.h"
#include "content/common/media/cdm_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "media/base/browser_cdm.h"
#include "media/base/browser_cdm_factory.h"
#include "media/base/media_switches.h"
namespace content {
using media::BrowserCdm;
using media::MediaKeys;
// Maximum lengths for various EME API parameters. These are checks to
// prevent unnecessarily large parameters from being passed around, and the
// lengths are somewhat arbitrary as the EME spec doesn't specify any limits.
const size_t kMaxInitDataLength = 64 * 1024; // 64 KB
const size_t kMaxSessionResponseLength = 64 * 1024; // 64 KB
const size_t kMaxKeySystemLength = 256;
// static
BrowserCdmManager* BrowserCdmManager::Create(RenderFrameHost* rfh) {
return new BrowserCdmManager(rfh);
}
BrowserCdmManager::BrowserCdmManager(RenderFrameHost* render_frame_host)
: render_frame_host_(render_frame_host),
web_contents_(WebContents::FromRenderFrameHost(render_frame_host)),
weak_ptr_factory_(this) {
}
BrowserCdmManager::~BrowserCdmManager() {
STLDeleteValues(&cdm_map_);
}
BrowserCdm* BrowserCdmManager::GetCdm(int cdm_id) {
CdmMap::const_iterator iter = cdm_map_.find(cdm_id);
return (iter == cdm_map_.end()) ? NULL : iter->second;
}
void BrowserCdmManager::OnSessionCreated(
int cdm_id,
uint32 session_id,
const std::string& web_session_id) {
Send(new CdmMsg_SessionCreated(
RoutingID(), cdm_id, session_id, web_session_id));
}
void BrowserCdmManager::OnSessionMessage(
int cdm_id,
uint32 session_id,
const std::vector<uint8>& message,
const GURL& destination_url) {
GURL verified_gurl = destination_url;
if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) {
DLOG(WARNING) << "SessionMessage destination_url is invalid : "
<< destination_url.possibly_invalid_spec();
verified_gurl = GURL::EmptyGURL(); // Replace invalid destination_url.
}
Send(new CdmMsg_SessionMessage(
RoutingID(), cdm_id, session_id, message, verified_gurl));
}
void BrowserCdmManager::OnSessionReady(int cdm_id, uint32 session_id) {
Send(new CdmMsg_SessionReady(RoutingID(), cdm_id, session_id));
}
void BrowserCdmManager::OnSessionClosed(int cdm_id, uint32 session_id) {
Send(new CdmMsg_SessionClosed(RoutingID(), cdm_id, session_id));
}
void BrowserCdmManager::OnSessionError(int cdm_id,
uint32 session_id,
MediaKeys::KeyError error_code,
uint32 system_code) {
Send(new CdmMsg_SessionError(
RoutingID(), cdm_id, session_id, error_code, system_code));
}
void BrowserCdmManager::OnInitializeCdm(int cdm_id,
const std::string& key_system,
const GURL& security_origin) {
if (key_system.size() > kMaxKeySystemLength) {
// This failure will be discovered and reported by OnCreateSession()
// as GetCdm() will return null.
NOTREACHED() << "Invalid key system: " << key_system;
return;
}
AddCdm(cdm_id, key_system, security_origin);
}
void BrowserCdmManager::OnCreateSession(
int cdm_id,
uint32 session_id,
CdmHostMsg_CreateSession_ContentType content_type,
const std::vector<uint8>& init_data) {
if (init_data.size() > kMaxInitDataLength) {
LOG(WARNING) << "InitData for ID: " << cdm_id
<< " too long: " << init_data.size();
OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
return;
}
// Convert the session content type into a MIME type. "audio" and "video"
// don't matter, so using "video" for the MIME type.
// Ref:
// https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypted-media.html#dom-createsession
std::string mime_type;
switch (content_type) {
case CREATE_SESSION_TYPE_WEBM:
mime_type = "video/webm";
break;
case CREATE_SESSION_TYPE_MP4:
mime_type = "video/mp4";
break;
default:
NOTREACHED();
return;
}
#if defined(OS_ANDROID)
if (CommandLine::ForCurrentProcess()
->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) {
CreateSessionIfPermitted(cdm_id, session_id, mime_type, init_data, true);
return;
}
#endif
BrowserCdm* cdm = GetCdm(cdm_id);
if (!cdm) {
DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
return;
}
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, MediaKeys::kUnknownError, 0);
return;
}
context->RequestProtectedMediaIdentifierPermission(
web_contents_->GetRenderProcessHost()->GetID(),
web_contents_->GetRenderViewHost()->GetRoutingID(),
iter->second,
base::Bind(&BrowserCdmManager::CreateSessionIfPermitted,
weak_ptr_factory_.GetWeakPtr(),
cdm_id,
session_id,
mime_type,
init_data));
}
void BrowserCdmManager::OnUpdateSession(
int cdm_id,
uint32 session_id,
const std::vector<uint8>& response) {
BrowserCdm* cdm = GetCdm(cdm_id);
if (!cdm) {
DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
return;
}
if (response.size() > kMaxSessionResponseLength) {
LOG(WARNING) << "Response for ID " << cdm_id
<< " is too long: " << response.size();
OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
return;
}
cdm->UpdateSession(session_id, &response[0], response.size());
}
void BrowserCdmManager::OnReleaseSession(int cdm_id, uint32 session_id) {
BrowserCdm* cdm = GetCdm(cdm_id);
if (!cdm) {
DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
return;
}
cdm->ReleaseSession(session_id);
}
void BrowserCdmManager::OnDestroyCdm(int cdm_id) {
BrowserCdm* cdm = GetCdm(cdm_id);
if (!cdm)
return;
CancelAllPendingSessionCreations(cdm_id);
RemoveCdm(cdm_id);
}
void BrowserCdmManager::CancelAllPendingSessionCreations(int cdm_id) {
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())
return;
context->CancelProtectedMediaIdentifierPermissionRequests(
web_contents_->GetRenderProcessHost()->GetID(),
web_contents_->GetRenderViewHost()->GetRoutingID(),
iter->second);
}
void BrowserCdmManager::AddCdm(int cdm_id,
const std::string& key_system,
const GURL& security_origin) {
DCHECK(!GetCdm(cdm_id));
base::WeakPtr<BrowserCdmManager> weak_this = weak_ptr_factory_.GetWeakPtr();
scoped_ptr<BrowserCdm> cdm(media::CreateBrowserCdm(
key_system,
base::Bind(&BrowserCdmManager::OnSessionCreated, weak_this, cdm_id),
base::Bind(&BrowserCdmManager::OnSessionMessage, weak_this, cdm_id),
base::Bind(&BrowserCdmManager::OnSessionReady, weak_this, cdm_id),
base::Bind(&BrowserCdmManager::OnSessionClosed, weak_this, cdm_id),
base::Bind(&BrowserCdmManager::OnSessionError, weak_this, cdm_id)));
if (!cdm) {
// This failure will be discovered and reported by OnCreateSession()
// as GetCdm() will return null.
DVLOG(1) << "failed to create CDM.";
return;
}
cdm_map_[cdm_id] = cdm.release();
cdm_security_origin_map_[cdm_id] = security_origin;
}
void BrowserCdmManager::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.
CdmMap::iterator iter = cdm_map_.find(cdm_id);
if (iter != cdm_map_.end()) {
delete iter->second;
cdm_map_.erase(iter);
}
cdm_security_origin_map_.erase(cdm_id);
}
int BrowserCdmManager::RoutingID() {
return render_frame_host_->GetRoutingID();
}
bool BrowserCdmManager::Send(IPC::Message* msg) {
return render_frame_host_->Send(msg);
}
void BrowserCdmManager::CreateSessionIfPermitted(
int cdm_id,
uint32 session_id,
const std::string& content_type,
const std::vector<uint8>& init_data,
bool permitted) {
if (!permitted) {
OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
return;
}
BrowserCdm* cdm = GetCdm(cdm_id);
if (!cdm) {
DLOG(WARNING) << "No CDM for ID: " << cdm_id << " found";
OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
return;
}
// This could fail, in which case a SessionError will be fired.
cdm->CreateSession(session_id, content_type, &init_data[0], init_data.size());
}
} // namespace content
// 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_BROWSER_MEDIA_ANDROID_BROWSER_CDM_MANAGER_H_
#define CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_CDM_MANAGER_H_
#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "content/common/content_export.h"
#include "content/common/media/cdm_messages_enums.h"
#include "ipc/ipc_message.h"
// TODO(xhwang): Drop this when KeyError is moved to a common header.
#include "media/base/media_keys.h"
#include "url/gurl.h"
namespace media {
class BrowserCdm;
}
namespace content {
class RenderFrameHost;
class WebContents;
// This class manages all CDM objects. It receives control operations from the
// the render process, and forwards them to corresponding CDM object. Callbacks
// from CDM objects are converted to IPCs and then sent to the render process.
class CONTENT_EXPORT BrowserCdmManager {
public:
// Creates a new BrowserCdmManager for |rfh|.
static BrowserCdmManager* Create(RenderFrameHost* rfh);
~BrowserCdmManager();
media::BrowserCdm* GetCdm(int cdm_id);
// CDM callbacks.
void OnSessionCreated(int cdm_id,
uint32 session_id,
const std::string& web_session_id);
void OnSessionMessage(int cdm_id,
uint32 session_id,
const std::vector<uint8>& message,
const GURL& destination_url);
void OnSessionReady(int cdm_id, uint32 session_id);
void OnSessionClosed(int cdm_id, uint32 session_id);
void OnSessionError(int cdm_id,
uint32 session_id,
media::MediaKeys::KeyError error_code,
uint32 system_code);
// Message handlers.
void OnInitializeCdm(int cdm_id,
const std::string& key_system,
const GURL& frame_url);
void OnCreateSession(int cdm_id,
uint32 session_id,
CdmHostMsg_CreateSession_ContentType content_type,
const std::vector<uint8>& init_data);
void OnUpdateSession(int cdm_id,
uint32 session_id,
const std::vector<uint8>& response);
void OnReleaseSession(int cdm_id, uint32 session_id);
void OnSetCdm(int player_id, int cdm_id);
void OnDestroyCdm(int cdm_id);
private:
// Clients must use Create() or subclass constructor.
explicit BrowserCdmManager(RenderFrameHost* render_frame_host);
// Cancels all pending session creations associated with |cdm_id|.
void CancelAllPendingSessionCreations(int cdm_id);
// 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 CDM with the specified id.
void RemoveCdm(int cdm_id);
int RoutingID();
// Helper function to send messages to RenderFrameObserver.
bool Send(IPC::Message* msg);
// If |permitted| is false, it does nothing but send
// |CdmMsg_SessionError| IPC message.
// The primary use case is infobar permission callback, i.e., when infobar
// can decide user's intention either from interacting with the actual info
// bar or from the saved preference.
void CreateSessionIfPermitted(int cdm_id,
uint32 session_id,
const std::string& content_type,
const std::vector<uint8>& init_data,
bool permitted);
RenderFrameHost* const render_frame_host_;
WebContents* const web_contents_;
// A map from CDM IDs to managed CDMs.
// TODO(xhwang): Use ScopedPtrHashMap for CdmMap.
typedef std::map<int, media::BrowserCdm*> CdmMap;
CdmMap cdm_map_;
// Map from CDM ID to CDM's security origin.
std::map<int, GURL> cdm_security_origin_map_;
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<BrowserCdmManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BrowserCdmManager);
};
} // namespace content
#endif // CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_CDM_MANAGER_H_
...@@ -5,11 +5,6 @@ ...@@ -5,11 +5,6 @@
#ifndef CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_MEDIA_PLAYER_MANAGER_H_ #ifndef CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_MEDIA_PLAYER_MANAGER_H_
#define CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_MEDIA_PLAYER_MANAGER_H_ #define CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_MEDIA_PLAYER_MANAGER_H_
#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
...@@ -17,17 +12,14 @@ ...@@ -17,17 +12,14 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "content/browser/android/content_video_view.h" #include "content/browser/android/content_video_view.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/common/media/cdm_messages_enums.h"
#include "content/common/media/media_player_messages_enums_android.h" #include "content/common/media/media_player_messages_enums_android.h"
#include "ipc/ipc_message.h" #include "ipc/ipc_message.h"
#include "media/base/android/media_player_android.h" #include "media/base/android/media_player_android.h"
#include "media/base/android/media_player_manager.h" #include "media/base/android/media_player_manager.h"
#include "media/base/media_keys.h"
#include "ui/gfx/rect_f.h" #include "ui/gfx/rect_f.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace media { namespace media {
class BrowserCdm;
class DemuxerAndroid; class DemuxerAndroid;
} }
...@@ -38,11 +30,11 @@ class ExternalVideoSurfaceContainer; ...@@ -38,11 +30,11 @@ class ExternalVideoSurfaceContainer;
class RenderFrameHost; class RenderFrameHost;
class WebContents; class WebContents;
// This class manages all the MediaPlayerAndroid and CDM objects. // This class manages all the MediaPlayerAndroid objects.
// It receives control operations from the the render process, and forwards // It receives control operations from the the render process, and forwards
// them to corresponding MediaPlayerAndroid or CDM object. Callbacks from // them to corresponding MediaPlayerAndroid object. Callbacks from
// MediaPlayerAndroid and CDM objects are converted to IPCs and then sent to // MediaPlayerAndroid objects are converted to IPCs and then sent to the render
// the render process. // process.
class CONTENT_EXPORT BrowserMediaPlayerManager class CONTENT_EXPORT BrowserMediaPlayerManager
: public media::MediaPlayerManager { : public media::MediaPlayerManager {
public: public:
...@@ -92,22 +84,8 @@ class CONTENT_EXPORT BrowserMediaPlayerManager ...@@ -92,22 +84,8 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
virtual media::MediaResourceGetter* GetMediaResourceGetter() OVERRIDE; virtual media::MediaResourceGetter* GetMediaResourceGetter() OVERRIDE;
virtual media::MediaPlayerAndroid* GetFullscreenPlayer() OVERRIDE; virtual media::MediaPlayerAndroid* GetFullscreenPlayer() OVERRIDE;
virtual media::MediaPlayerAndroid* GetPlayer(int player_id) OVERRIDE; virtual media::MediaPlayerAndroid* GetPlayer(int player_id) OVERRIDE;
virtual media::BrowserCdm* GetCdm(int cdm_id) OVERRIDE;
virtual void DestroyAllMediaPlayers() OVERRIDE; virtual void DestroyAllMediaPlayers() OVERRIDE;
virtual void RequestFullScreen(int player_id) OVERRIDE; virtual void RequestFullScreen(int player_id) OVERRIDE;
virtual void OnSessionCreated(int cdm_id,
uint32 session_id,
const std::string& web_session_id) OVERRIDE;
virtual void OnSessionMessage(int cdm_id,
uint32 session_id,
const std::vector<uint8>& message,
const GURL& 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,
uint32 session_id,
media::MediaKeys::KeyError error_code,
uint32 system_code) OVERRIDE;
#if defined(VIDEO_HOLE) #if defined(VIDEO_HOLE)
void AttachExternalVideoSurface(int player_id, jobject surface); void AttachExternalVideoSurface(int player_id, jobject surface);
...@@ -132,19 +110,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager ...@@ -132,19 +110,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
virtual void OnReleaseResources(int player_id); virtual void OnReleaseResources(int player_id);
virtual void OnDestroyPlayer(int player_id); virtual void OnDestroyPlayer(int player_id);
virtual void ReleaseFullscreenPlayer(media::MediaPlayerAndroid* player); virtual void ReleaseFullscreenPlayer(media::MediaPlayerAndroid* player);
void OnInitializeCdm(int cdm_id,
const std::string& key_system,
const GURL& frame_url);
void OnCreateSession(int cdm_id,
uint32 session_id,
CdmHostMsg_CreateSession_ContentType content_type,
const std::vector<uint8>& init_data);
void OnUpdateSession(int cdm_id,
uint32 session_id,
const std::vector<uint8>& response);
void OnReleaseSession(int cdm_id, uint32 session_id);
void OnSetCdm(int player_id, int cdm_id);
void OnDestroyCdm(int cdm_id);
#if defined(VIDEO_HOLE) #if defined(VIDEO_HOLE)
void OnNotifyExternalSurface( void OnNotifyExternalSurface(
int player_id, bool is_request, const gfx::RectF& rect); int player_id, bool is_request, const gfx::RectF& rect);
...@@ -156,9 +121,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager ...@@ -156,9 +121,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
WebContents* web_contents() const { return web_contents_; } WebContents* web_contents() const { return web_contents_; }
// Cancels all pending session creations associated with |cdm_id|.
void CancelAllPendingSessionCreations(int cdm_id);
// Adds a given player to the list. // Adds a given player to the list.
void AddPlayer(media::MediaPlayerAndroid* player); void AddPlayer(media::MediaPlayerAndroid* player);
...@@ -172,32 +134,12 @@ class CONTENT_EXPORT BrowserMediaPlayerManager ...@@ -172,32 +134,12 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
int player_id, int player_id,
media::MediaPlayerAndroid* player); media::MediaPlayerAndroid* player);
// 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 CDM with the specified id.
void RemoveCdm(int cdm_id);
int RoutingID(); int RoutingID();
// Helper function to send messages to RenderFrameObserver. // Helper function to send messages to RenderFrameObserver.
bool Send(IPC::Message* msg); bool Send(IPC::Message* msg);
private: private:
// If |permitted| is false, it does nothing but send
// |CdmMsg_SessionError| IPC message.
// The primary use case is infobar permission callback, i.e., when infobar
// can decide user's intention either from interacting with the actual info
// bar or from the saved preference.
void CreateSessionIfPermitted(int cdm_id,
uint32 session_id,
const std::string& content_type,
const std::vector<uint8>& init_data,
bool permitted);
// Constructs a MediaPlayerAndroid object. // Constructs a MediaPlayerAndroid object.
media::MediaPlayerAndroid* CreateMediaPlayer( media::MediaPlayerAndroid* CreateMediaPlayer(
MediaPlayerHostMsg_Initialize_Type type, MediaPlayerHostMsg_Initialize_Type type,
...@@ -229,13 +171,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager ...@@ -229,13 +171,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
// An array of managed players. // An array of managed players.
ScopedVector<media::MediaPlayerAndroid> players_; ScopedVector<media::MediaPlayerAndroid> players_;
// A map from CDM IDs to managed CDMs.
typedef std::map<int, media::BrowserCdm*> CdmMap;
CdmMap cdm_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 // The fullscreen video view object or NULL if video is not played in
// fullscreen. // fullscreen.
scoped_ptr<ContentVideoView> video_view_; scoped_ptr<ContentVideoView> video_view_;
......
...@@ -4,16 +4,22 @@ ...@@ -4,16 +4,22 @@
#include "content/browser/media/android/media_web_contents_observer.h" #include "content/browser/media/android/media_web_contents_observer.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "content/browser/media/android/browser_cdm_manager.h"
#include "content/browser/media/android/browser_media_player_manager.h" #include "content/browser/media/android/browser_media_player_manager.h"
#include "content/common/media/cdm_messages.h" #include "content/common/media/cdm_messages.h"
#include "content/common/media/media_player_messages_android.h" #include "content/common/media/media_player_messages_android.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "ipc/ipc_message_macros.h" #include "ipc/ipc_message_macros.h"
#include "media/base/android/media_player_android.h"
namespace content { namespace content {
using media::BrowserCdm;
using media::MediaPlayerAndroid;
MediaWebContentsObserver::MediaWebContentsObserver( MediaWebContentsObserver::MediaWebContentsObserver(
RenderViewHost* render_view_host) RenderViewHost* render_view_host)
: WebContentsObserver(WebContents::FromRenderViewHost(render_view_host)) { : WebContentsObserver(WebContents::FromRenderViewHost(render_view_host)) {
...@@ -26,90 +32,151 @@ void MediaWebContentsObserver::RenderFrameDeleted( ...@@ -26,90 +32,151 @@ void MediaWebContentsObserver::RenderFrameDeleted(
RenderFrameHost* render_frame_host) { RenderFrameHost* render_frame_host) {
uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host); uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
media_player_managers_.erase(key); media_player_managers_.erase(key);
cdm_managers_.erase(key);
} }
bool MediaWebContentsObserver::OnMessageReceived( bool MediaWebContentsObserver::OnMessageReceived(
const IPC::Message& msg, const IPC::Message& msg,
RenderFrameHost* render_frame_host) { RenderFrameHost* render_frame_host) {
BrowserMediaPlayerManager* player_manager = if (OnMediaPlayerMessageReceived(msg, render_frame_host))
GetMediaPlayerManager(render_frame_host); return true;
DCHECK(player_manager);
if (OnCdmMessageReceived(msg, render_frame_host))
return true;
if (OnMediaPlayerSetCdmMessageReceived(msg, render_frame_host))
return true;
return false;
}
bool MediaWebContentsObserver::OnMediaPlayerMessageReceived(
const IPC::Message& msg,
RenderFrameHost* render_frame_host) {
bool handled = true; bool handled = true;
IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserver, msg) IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserver, msg)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_EnterFullscreen, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_EnterFullscreen,
player_manager, GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnEnterFullscreen) BrowserMediaPlayerManager::OnEnterFullscreen)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_ExitFullscreen, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_ExitFullscreen,
player_manager, GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnExitFullscreen) BrowserMediaPlayerManager::OnExitFullscreen)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Initialize, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Initialize,
player_manager, GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnInitialize) BrowserMediaPlayerManager::OnInitialize)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Start, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Start,
player_manager, GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnStart) BrowserMediaPlayerManager::OnStart)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Seek, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Seek,
player_manager, GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnSeek) BrowserMediaPlayerManager::OnSeek)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Pause, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Pause,
player_manager, GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnPause) BrowserMediaPlayerManager::OnPause)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetVolume, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetVolume,
player_manager, GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnSetVolume) BrowserMediaPlayerManager::OnSetVolume)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetPoster, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetPoster,
player_manager, GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnSetPoster) BrowserMediaPlayerManager::OnSetPoster)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Release, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Release,
player_manager, GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnReleaseResources) BrowserMediaPlayerManager::OnReleaseResources)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyMediaPlayer, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyMediaPlayer,
player_manager, GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnDestroyPlayer) BrowserMediaPlayerManager::OnDestroyPlayer)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyAllMediaPlayers, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyAllMediaPlayers,
player_manager, GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::DestroyAllMediaPlayers) BrowserMediaPlayerManager::DestroyAllMediaPlayers)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetCdm, #if defined(VIDEO_HOLE)
player_manager, IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_NotifyExternalSurface,
BrowserMediaPlayerManager::OnSetCdm) GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnNotifyExternalSurface)
#endif // defined(VIDEO_HOLE)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
bool MediaWebContentsObserver::OnCdmMessageReceived(
const IPC::Message& msg,
RenderFrameHost* render_frame_host) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserver, msg)
IPC_MESSAGE_FORWARD(CdmHostMsg_InitializeCdm, IPC_MESSAGE_FORWARD(CdmHostMsg_InitializeCdm,
player_manager, GetCdmManager(render_frame_host),
BrowserMediaPlayerManager::OnInitializeCdm) BrowserCdmManager::OnInitializeCdm)
IPC_MESSAGE_FORWARD(CdmHostMsg_CreateSession, IPC_MESSAGE_FORWARD(CdmHostMsg_CreateSession,
player_manager, GetCdmManager(render_frame_host),
BrowserMediaPlayerManager::OnCreateSession) BrowserCdmManager::OnCreateSession)
IPC_MESSAGE_FORWARD(CdmHostMsg_UpdateSession, IPC_MESSAGE_FORWARD(CdmHostMsg_UpdateSession,
player_manager, GetCdmManager(render_frame_host),
BrowserMediaPlayerManager::OnUpdateSession) BrowserCdmManager::OnUpdateSession)
IPC_MESSAGE_FORWARD(CdmHostMsg_ReleaseSession, IPC_MESSAGE_FORWARD(CdmHostMsg_ReleaseSession,
player_manager, GetCdmManager(render_frame_host),
BrowserMediaPlayerManager::OnReleaseSession) BrowserCdmManager::OnReleaseSession)
IPC_MESSAGE_FORWARD(CdmHostMsg_DestroyCdm, IPC_MESSAGE_FORWARD(CdmHostMsg_DestroyCdm,
player_manager, GetCdmManager(render_frame_host),
BrowserMediaPlayerManager::OnDestroyCdm) BrowserCdmManager::OnDestroyCdm)
#if defined(VIDEO_HOLE)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_NotifyExternalSurface,
player_manager,
BrowserMediaPlayerManager::OnNotifyExternalSurface)
#endif // defined(VIDEO_HOLE)
IPC_MESSAGE_UNHANDLED(handled = false) IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP() IPC_END_MESSAGE_MAP()
return handled; return handled;
} }
bool MediaWebContentsObserver::OnMediaPlayerSetCdmMessageReceived(
const IPC::Message& msg,
RenderFrameHost* render_frame_host) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(
MediaWebContentsObserver, msg, render_frame_host)
IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetCdm, OnSetCdm)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void MediaWebContentsObserver::OnSetCdm(RenderFrameHost* render_frame_host,
int player_id,
int cdm_id) {
MediaPlayerAndroid* media_player =
GetMediaPlayerManager(render_frame_host)->GetPlayer(player_id);
if (!media_player) {
NOTREACHED() << "OnSetCdm: MediaPlayer not found for " << player_id;
return;
}
BrowserCdm* cdm = GetCdmManager(render_frame_host)->GetCdm(cdm_id);
if (!cdm) {
NOTREACHED() << "OnSetCdm: CDM not found for " << cdm_id;
return;
}
// TODO(xhwang): This could possibly fail. In that case we should reject the
// promise.
media_player->SetCdm(cdm);
}
BrowserMediaPlayerManager* MediaWebContentsObserver::GetMediaPlayerManager( BrowserMediaPlayerManager* MediaWebContentsObserver::GetMediaPlayerManager(
RenderFrameHost* render_frame_host) { RenderFrameHost* render_frame_host) {
uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host); uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
if (!media_player_managers_.contains(key)) { if (!media_player_managers_.contains(key)) {
media_player_managers_.set( media_player_managers_.set(
key, key,
scoped_ptr<BrowserMediaPlayerManager>( make_scoped_ptr(BrowserMediaPlayerManager::Create(render_frame_host)));
BrowserMediaPlayerManager::Create(render_frame_host)));
} }
return media_player_managers_.get(key); return media_player_managers_.get(key);
} }
BrowserCdmManager* MediaWebContentsObserver::GetCdmManager(
RenderFrameHost* render_frame_host) {
uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
if (!cdm_managers_.contains(key)) {
cdm_managers_.set(
key, make_scoped_ptr(BrowserCdmManager::Create(render_frame_host)));
}
return cdm_managers_.get(key);
}
void MediaWebContentsObserver::PauseVideo() { void MediaWebContentsObserver::PauseVideo() {
for (MediaPlayerManagerMap::iterator iter = media_player_managers_.begin(); for (MediaPlayerManagerMap::iterator iter = media_player_managers_.begin();
iter != media_player_managers_.end(); ++iter) { iter != media_player_managers_.end(); ++iter) {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
namespace content { namespace content {
class BrowserCdmManager;
class BrowserMediaPlayerManager; class BrowserMediaPlayerManager;
class RenderViewHost; class RenderViewHost;
...@@ -29,11 +30,26 @@ class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver { ...@@ -29,11 +30,26 @@ class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver {
virtual bool OnMessageReceived(const IPC::Message& message, virtual bool OnMessageReceived(const IPC::Message& message,
RenderFrameHost* render_frame_host) OVERRIDE; RenderFrameHost* render_frame_host) OVERRIDE;
// Helper functions to handle various IPC messages. Returns whether the
// |message| is handled in the function.
bool OnMediaPlayerMessageReceived(const IPC::Message& message,
RenderFrameHost* render_frame_host);
bool OnCdmMessageReceived(const IPC::Message& message,
RenderFrameHost* render_frame_host);
bool OnMediaPlayerSetCdmMessageReceived(const IPC::Message& message,
RenderFrameHost* render_frame_host);
// Gets the media player manager associated with |render_frame_host|. Creates // Gets the media player manager associated with |render_frame_host|. Creates
// a new one if it doesn't exist. The caller doesn't own the returned pointer. // a new one if it doesn't exist. The caller doesn't own the returned pointer.
BrowserMediaPlayerManager* GetMediaPlayerManager( BrowserMediaPlayerManager* GetMediaPlayerManager(
RenderFrameHost* render_frame_host); RenderFrameHost* render_frame_host);
// Gets the CDM manager associated with |render_frame_host|. Creates
// a new one if it doesn't exist. The caller doesn't own the returned pointer.
BrowserCdmManager* GetCdmManager(RenderFrameHost* render_frame_host);
void OnSetCdm(RenderFrameHost* render_frame_host, int player_id, int cdm_id);
// Pauses all media player. // Pauses all media player.
void PauseVideo(); void PauseVideo();
...@@ -47,6 +63,10 @@ class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver { ...@@ -47,6 +63,10 @@ class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver {
MediaPlayerManagerMap; MediaPlayerManagerMap;
MediaPlayerManagerMap media_player_managers_; MediaPlayerManagerMap media_player_managers_;
// Map from RenderFrameHost* to BrowserCdmManager.
typedef base::ScopedPtrHashMap<uintptr_t, BrowserCdmManager> CdmManagerMap;
CdmManagerMap cdm_managers_;
DISALLOW_COPY_AND_ASSIGN(MediaWebContentsObserver); DISALLOW_COPY_AND_ASSIGN(MediaWebContentsObserver);
}; };
......
...@@ -781,6 +781,8 @@ ...@@ -781,6 +781,8 @@
'browser/loader/upload_data_stream_builder.h', 'browser/loader/upload_data_stream_builder.h',
'browser/mach_broker_mac.h', 'browser/mach_broker_mac.h',
'browser/mach_broker_mac.mm', 'browser/mach_broker_mac.mm',
'browser/media/android/browser_cdm_manager.cc',
'browser/media/android/browser_cdm_manager.h',
'browser/media/android/browser_demuxer_android.cc', 'browser/media/android/browser_demuxer_android.cc',
'browser/media/android/browser_demuxer_android.h', 'browser/media/android/browser_demuxer_android.h',
'browser/media/android/browser_media_player_manager.cc', 'browser/media/android/browser_media_player_manager.cc',
......
...@@ -5,21 +5,13 @@ ...@@ -5,21 +5,13 @@
#ifndef MEDIA_BASE_ANDROID_MEDIA_PLAYER_MANAGER_H_ #ifndef MEDIA_BASE_ANDROID_MEDIA_PLAYER_MANAGER_H_
#define MEDIA_BASE_ANDROID_MEDIA_PLAYER_MANAGER_H_ #define MEDIA_BASE_ANDROID_MEDIA_PLAYER_MANAGER_H_
#include <string>
#include <vector>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "media/base/android/demuxer_stream_player_params.h" #include "media/base/android/demuxer_stream_player_params.h"
#include "media/base/media_export.h" #include "media/base/media_export.h"
#include "media/base/media_keys.h"
#include "url/gurl.h"
class GURL;
namespace media { namespace media {
class BrowserCdm;
class MediaPlayerAndroid; class MediaPlayerAndroid;
class MediaResourceGetter; class MediaResourceGetter;
...@@ -74,39 +66,8 @@ class MEDIA_EXPORT MediaPlayerManager { ...@@ -74,39 +66,8 @@ class MEDIA_EXPORT MediaPlayerManager {
// Release all the players managed by this object. // Release all the players managed by this object.
virtual void DestroyAllMediaPlayers() = 0; virtual void DestroyAllMediaPlayers() = 0;
// Get the CDM for the given CDM ID.
virtual BrowserCdm* GetCdm(int cdm_id) = 0;
// Called by the player to get a hardware protected surface. // Called by the player to get a hardware protected surface.
virtual void RequestFullScreen(int player_id) = 0; virtual void RequestFullScreen(int player_id) = 0;
// The following five methods are related to EME.
// TODO(xhwang): These methods needs to be decoupled from MediaPlayerManager
// to support the W3C Working Draft version of the EME spec.
// http://crbug.com/315312
// Called when CDM creates a session.
virtual void OnSessionCreated(int cdm_id,
uint32 session_id,
const std::string& web_session_id) = 0;
// 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;
// Called when CDM wants to send a Ready event.
virtual void OnSessionReady(int cdm_id, uint32 session_id) = 0;
// Called when CDM wants to send a Closed event.
virtual void OnSessionClosed(int cdm_id, uint32 session_id) = 0;
// Called when CDM wants to send an Error event.
virtual void OnSessionError(int cdm_id,
uint32 session_id,
MediaKeys::KeyError error_code,
uint32 system_code) = 0;
}; };
} // namespace media } // namespace media
......
...@@ -74,21 +74,7 @@ class MockMediaPlayerManager : public MediaPlayerManager { ...@@ -74,21 +74,7 @@ class MockMediaPlayerManager : public MediaPlayerManager {
virtual MediaPlayerAndroid* GetFullscreenPlayer() OVERRIDE { return NULL; } virtual MediaPlayerAndroid* GetFullscreenPlayer() OVERRIDE { return NULL; }
virtual MediaPlayerAndroid* GetPlayer(int player_id) OVERRIDE { return NULL; } virtual MediaPlayerAndroid* GetPlayer(int player_id) OVERRIDE { return NULL; }
virtual void DestroyAllMediaPlayers() OVERRIDE {} virtual void DestroyAllMediaPlayers() OVERRIDE {}
virtual BrowserCdm* GetCdm(int cdm_id) OVERRIDE { return NULL; }
virtual void RequestFullScreen(int player_id) OVERRIDE {} virtual void RequestFullScreen(int player_id) OVERRIDE {}
virtual void OnSessionCreated(int cdm_id,
uint32 session_id,
const std::string& web_session_id) OVERRIDE {}
virtual void OnSessionMessage(int cdm_id,
uint32 session_id,
const std::vector<uint8>& message,
const GURL& 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,
uint32 session_id,
MediaKeys::KeyError error_code,
uint32 system_code) OVERRIDE {}
bool playback_completed() const { bool playback_completed() const {
return playback_completed_; return playback_completed_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment