summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-07 20:28:18 +0000
committerxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-07 20:28:18 +0000
commit8fc0f5be02eee83d34830fe0605b30ab36a06d18 (patch)
tree55ee9fd848fbc5e24452b153f77a2bba453ccf84 /content
parent03406ba721ebad5e4c6a1dba17a0b3f7fbe0ec4c (diff)
downloadchromium_src-8fc0f5be02eee83d34830fe0605b30ab36a06d18.zip
chromium_src-8fc0f5be02eee83d34830fe0605b30ab36a06d18.tar.gz
chromium_src-8fc0f5be02eee83d34830fe0605b30ab36a06d18.tar.bz2
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
Diffstat (limited to 'content')
-rw-r--r--content/browser/media/android/browser_cdm_manager.cc294
-rw-r--r--content/browser/media/android/browser_cdm_manager.h125
-rw-r--r--content/browser/media/android/browser_media_player_manager.cc270
-rw-r--r--content/browser/media/android/browser_media_player_manager.h73
-rw-r--r--content/browser/media/android/media_web_contents_observer.cc135
-rw-r--r--content/browser/media/android/media_web_contents_observer.h20
-rw-r--r--content/content_browser.gypi2
7 files changed, 546 insertions, 373 deletions
diff --git a/content/browser/media/android/browser_cdm_manager.cc b/content/browser/media/android/browser_cdm_manager.cc
new file mode 100644
index 0000000..20013ec
--- /dev/null
+++ b/content/browser/media/android/browser_cdm_manager.cc
@@ -0,0 +1,294 @@
+// 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
diff --git a/content/browser/media/android/browser_cdm_manager.h b/content/browser/media/android/browser_cdm_manager.h
new file mode 100644
index 0000000..d55c50c
--- /dev/null
+++ b/content/browser/media/android/browser_cdm_manager.h
@@ -0,0 +1,125 @@
+// 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_
diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc
index a4c5e0a..c2e4df6 100644
--- a/content/browser/media/android/browser_media_player_manager.cc
+++ b/content/browser/media/android/browser_media_player_manager.cc
@@ -6,13 +6,11 @@
#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"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_view_android.h"
-#include "content/common/media/cdm_messages.h"
#include "content/common/media/media_player_messages_android.h"
#include "content/public/browser/android/content_view_core.h"
#include "content/public/browser/android/external_video_surface_container.h"
@@ -28,12 +26,8 @@
#include "content/public/common/content_switches.h"
#include "media/base/android/media_player_bridge.h"
#include "media/base/android/media_source_player.h"
-#include "media/base/browser_cdm.h"
-#include "media/base/browser_cdm_factory.h"
#include "media/base/media_switches.h"
-using media::BrowserCdm;
-using media::MediaKeys;
using media::MediaPlayerAndroid;
using media::MediaPlayerBridge;
using media::MediaPlayerManager;
@@ -45,13 +39,6 @@ namespace content {
// attempting to release inactive media players.
const int kMediaPlayerThreshold = 1;
-// 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 BrowserMediaPlayerManager::Factory g_factory = NULL;
// static
@@ -319,14 +306,8 @@ MediaPlayerAndroid* BrowserMediaPlayerManager::GetPlayer(int player_id) {
return NULL;
}
-BrowserCdm* 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();
- STLDeleteValues(&cdm_map_);
if (fullscreen_player_id_ != -1) {
video_view_.reset();
fullscreen_player_id_ = -1;
@@ -344,48 +325,6 @@ void BrowserMediaPlayerManager::RequestFullScreen(int player_id) {
}
}
-// The following 5 functions are EME MediaKeySession events.
-
-void BrowserMediaPlayerManager::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 BrowserMediaPlayerManager::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 BrowserMediaPlayerManager::OnSessionReady(int cdm_id, uint32 session_id) {
- Send(new CdmMsg_SessionReady(RoutingID(), cdm_id, session_id));
-}
-
-void BrowserMediaPlayerManager::OnSessionClosed(int cdm_id, uint32 session_id) {
- Send(new CdmMsg_SessionClosed(RoutingID(), cdm_id, session_id));
-}
-
-void BrowserMediaPlayerManager::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));
-}
-
#if defined(VIDEO_HOLE)
void BrowserMediaPlayerManager::AttachExternalVideoSurface(int player_id,
jobject surface) {
@@ -556,139 +495,6 @@ void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) {
fullscreen_player_id_ = -1;
}
-void BrowserMediaPlayerManager::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 BrowserMediaPlayerManager::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 (CommandLine::ForCurrentProcess()
- ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) {
- CreateSessionIfPermitted(cdm_id, session_id, mime_type, init_data, true);
- 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;
- }
-
- 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(&BrowserMediaPlayerManager::CreateSessionIfPermitted,
- weak_ptr_factory_.GetWeakPtr(),
- cdm_id,
- session_id,
- mime_type,
- init_data));
-}
-
-void BrowserMediaPlayerManager::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 BrowserMediaPlayerManager::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 BrowserMediaPlayerManager::OnDestroyCdm(int cdm_id) {
- BrowserCdm* cdm = GetCdm(cdm_id);
- if (!cdm)
- return;
-
- CancelAllPendingSessionCreations(cdm_id);
- RemoveCdm(cdm_id);
-}
-
-void BrowserMediaPlayerManager::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 BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) {
DCHECK(!GetPlayer(player->player_id()));
players_.push_back(player);
@@ -720,60 +526,6 @@ scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer(
return scoped_ptr<media::MediaPlayerAndroid>(previous_player);
}
-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();
-
- int id = cdm_id;
- scoped_ptr<BrowserCdm> cdm(media::CreateBrowserCdm(
- key_system,
- base::Bind(&BrowserMediaPlayerManager::OnSessionCreated, weak_this, id),
- base::Bind(&BrowserMediaPlayerManager::OnSessionMessage, weak_this, id),
- base::Bind(&BrowserMediaPlayerManager::OnSessionReady, weak_this, id),
- base::Bind(&BrowserMediaPlayerManager::OnSessionClosed, weak_this, id),
- base::Bind(&BrowserMediaPlayerManager::OnSessionError, weak_this, 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 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.
- 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);
-}
-
-void BrowserMediaPlayerManager::OnSetCdm(int player_id, int cdm_id) {
- MediaPlayerAndroid* player = GetPlayer(player_id);
- BrowserCdm* cdm = GetCdm(cdm_id);
- // Currently we do not support detaching CDM from a player.
- if (!cdm || !player) {
- NOTREACHED() << "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->SetCdm(cdm);
-}
-
int BrowserMediaPlayerManager::RoutingID() {
return render_frame_host_->GetRoutingID();
}
@@ -782,28 +534,6 @@ bool BrowserMediaPlayerManager::Send(IPC::Message* msg) {
return render_frame_host_->Send(msg);
}
-void BrowserMediaPlayerManager::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());
-}
-
void BrowserMediaPlayerManager::ReleaseFullscreenPlayer(
MediaPlayerAndroid* player) {
player->Release();
diff --git a/content/browser/media/android/browser_media_player_manager.h b/content/browser/media/android/browser_media_player_manager.h
index b313b39..4da685e 100644
--- a/content/browser/media/android/browser_media_player_manager.h
+++ b/content/browser/media/android/browser_media_player_manager.h
@@ -5,11 +5,6 @@
#ifndef 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/callback.h"
#include "base/memory/scoped_ptr.h"
@@ -17,17 +12,14 @@
#include "base/time/time.h"
#include "content/browser/android/content_video_view.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 "ipc/ipc_message.h"
#include "media/base/android/media_player_android.h"
#include "media/base/android/media_player_manager.h"
-#include "media/base/media_keys.h"
#include "ui/gfx/rect_f.h"
#include "url/gurl.h"
namespace media {
-class BrowserCdm;
class DemuxerAndroid;
}
@@ -38,11 +30,11 @@ class ExternalVideoSurfaceContainer;
class RenderFrameHost;
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
-// them to corresponding MediaPlayerAndroid or CDM object. Callbacks from
-// MediaPlayerAndroid and CDM objects are converted to IPCs and then sent to
-// the render process.
+// them to corresponding MediaPlayerAndroid object. Callbacks from
+// MediaPlayerAndroid objects are converted to IPCs and then sent to the render
+// process.
class CONTENT_EXPORT BrowserMediaPlayerManager
: public media::MediaPlayerManager {
public:
@@ -92,22 +84,8 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
virtual media::MediaResourceGetter* GetMediaResourceGetter() OVERRIDE;
virtual media::MediaPlayerAndroid* GetFullscreenPlayer() OVERRIDE;
virtual media::MediaPlayerAndroid* GetPlayer(int player_id) OVERRIDE;
- virtual media::BrowserCdm* GetCdm(int cdm_id) OVERRIDE;
virtual void DestroyAllMediaPlayers() 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)
void AttachExternalVideoSurface(int player_id, jobject surface);
@@ -132,19 +110,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
virtual void OnReleaseResources(int player_id);
virtual void OnDestroyPlayer(int player_id);
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)
void OnNotifyExternalSurface(
int player_id, bool is_request, const gfx::RectF& rect);
@@ -156,9 +121,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
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.
void AddPlayer(media::MediaPlayerAndroid* player);
@@ -172,32 +134,12 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
int player_id,
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();
// Helper function to send messages to RenderFrameObserver.
bool Send(IPC::Message* msg);
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.
media::MediaPlayerAndroid* CreateMediaPlayer(
MediaPlayerHostMsg_Initialize_Type type,
@@ -229,13 +171,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
// An array of managed 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
// fullscreen.
scoped_ptr<ContentVideoView> video_view_;
diff --git a/content/browser/media/android/media_web_contents_observer.cc b/content/browser/media/android/media_web_contents_observer.cc
index 711375c..063085b 100644
--- a/content/browser/media/android/media_web_contents_observer.cc
+++ b/content/browser/media/android/media_web_contents_observer.cc
@@ -4,16 +4,22 @@
#include "content/browser/media/android/media_web_contents_observer.h"
+#include "base/memory/scoped_ptr.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/common/media/cdm_messages.h"
#include "content/common/media/media_player_messages_android.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message_macros.h"
+#include "media/base/android/media_player_android.h"
namespace content {
+using media::BrowserCdm;
+using media::MediaPlayerAndroid;
+
MediaWebContentsObserver::MediaWebContentsObserver(
RenderViewHost* render_view_host)
: WebContentsObserver(WebContents::FromRenderViewHost(render_view_host)) {
@@ -26,90 +32,151 @@ void MediaWebContentsObserver::RenderFrameDeleted(
RenderFrameHost* render_frame_host) {
uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
media_player_managers_.erase(key);
+ cdm_managers_.erase(key);
}
bool MediaWebContentsObserver::OnMessageReceived(
const IPC::Message& msg,
RenderFrameHost* render_frame_host) {
- BrowserMediaPlayerManager* player_manager =
- GetMediaPlayerManager(render_frame_host);
- DCHECK(player_manager);
+ if (OnMediaPlayerMessageReceived(msg, render_frame_host))
+ return true;
+
+ 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;
IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserver, msg)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_EnterFullscreen,
- player_manager,
+ GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnEnterFullscreen)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_ExitFullscreen,
- player_manager,
+ GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnExitFullscreen)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Initialize,
- player_manager,
+ GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnInitialize)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Start,
- player_manager,
+ GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnStart)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Seek,
- player_manager,
+ GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnSeek)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Pause,
- player_manager,
+ GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnPause)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetVolume,
- player_manager,
+ GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnSetVolume)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetPoster,
- player_manager,
+ GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnSetPoster)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Release,
- player_manager,
+ GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnReleaseResources)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyMediaPlayer,
- player_manager,
+ GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::OnDestroyPlayer)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_DestroyAllMediaPlayers,
- player_manager,
+ GetMediaPlayerManager(render_frame_host),
BrowserMediaPlayerManager::DestroyAllMediaPlayers)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_SetCdm,
- player_manager,
- BrowserMediaPlayerManager::OnSetCdm)
+#if defined(VIDEO_HOLE)
+ IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_NotifyExternalSurface,
+ 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,
- player_manager,
- BrowserMediaPlayerManager::OnInitializeCdm)
+ GetCdmManager(render_frame_host),
+ BrowserCdmManager::OnInitializeCdm)
IPC_MESSAGE_FORWARD(CdmHostMsg_CreateSession,
- player_manager,
- BrowserMediaPlayerManager::OnCreateSession)
+ GetCdmManager(render_frame_host),
+ BrowserCdmManager::OnCreateSession)
IPC_MESSAGE_FORWARD(CdmHostMsg_UpdateSession,
- player_manager,
- BrowserMediaPlayerManager::OnUpdateSession)
+ GetCdmManager(render_frame_host),
+ BrowserCdmManager::OnUpdateSession)
IPC_MESSAGE_FORWARD(CdmHostMsg_ReleaseSession,
- player_manager,
- BrowserMediaPlayerManager::OnReleaseSession)
+ GetCdmManager(render_frame_host),
+ BrowserCdmManager::OnReleaseSession)
IPC_MESSAGE_FORWARD(CdmHostMsg_DestroyCdm,
- player_manager,
- BrowserMediaPlayerManager::OnDestroyCdm)
-#if defined(VIDEO_HOLE)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_NotifyExternalSurface,
- player_manager,
- BrowserMediaPlayerManager::OnNotifyExternalSurface)
-#endif // defined(VIDEO_HOLE)
+ GetCdmManager(render_frame_host),
+ BrowserCdmManager::OnDestroyCdm)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
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(
RenderFrameHost* render_frame_host) {
uintptr_t key = reinterpret_cast<uintptr_t>(render_frame_host);
if (!media_player_managers_.contains(key)) {
media_player_managers_.set(
key,
- scoped_ptr<BrowserMediaPlayerManager>(
- BrowserMediaPlayerManager::Create(render_frame_host)));
+ make_scoped_ptr(BrowserMediaPlayerManager::Create(render_frame_host)));
}
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() {
for (MediaPlayerManagerMap::iterator iter = media_player_managers_.begin();
iter != media_player_managers_.end(); ++iter) {
diff --git a/content/browser/media/android/media_web_contents_observer.h b/content/browser/media/android/media_web_contents_observer.h
index 126bbfb..38b82b2 100644
--- a/content/browser/media/android/media_web_contents_observer.h
+++ b/content/browser/media/android/media_web_contents_observer.h
@@ -12,6 +12,7 @@
namespace content {
+class BrowserCdmManager;
class BrowserMediaPlayerManager;
class RenderViewHost;
@@ -29,11 +30,26 @@ class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver {
virtual bool OnMessageReceived(const IPC::Message& message,
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
// a new one if it doesn't exist. The caller doesn't own the returned pointer.
BrowserMediaPlayerManager* GetMediaPlayerManager(
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.
void PauseVideo();
@@ -47,6 +63,10 @@ class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver {
MediaPlayerManagerMap;
MediaPlayerManagerMap media_player_managers_;
+ // Map from RenderFrameHost* to BrowserCdmManager.
+ typedef base::ScopedPtrHashMap<uintptr_t, BrowserCdmManager> CdmManagerMap;
+ CdmManagerMap cdm_managers_;
+
DISALLOW_COPY_AND_ASSIGN(MediaWebContentsObserver);
};
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index e4d5803..4758aeb 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -781,6 +781,8 @@
'browser/loader/upload_data_stream_builder.h',
'browser/mach_broker_mac.h',
'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.h',
'browser/media/android/browser_media_player_manager.cc',