Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: content/browser/media/cdm/browser_cdm_manager.cc

Issue 2380743004: media: Remove Browser CDM implementation (Closed)
Patch Set: media: Remove Browser CDM implementation Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/media/cdm/browser_cdm_manager.cc
diff --git a/content/browser/media/cdm/browser_cdm_manager.cc b/content/browser/media/cdm/browser_cdm_manager.cc
deleted file mode 100644
index 7202c956f5f60b3bbda82f8ef7af1eb9722f7f1d..0000000000000000000000000000000000000000
--- a/content/browser/media/cdm/browser_cdm_manager.cc
+++ /dev/null
@@ -1,716 +0,0 @@
-// 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/cdm/browser_cdm_manager.h"
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/lazy_instance.h"
-#include "base/task_runner.h"
-#include "build/build_config.h"
-#include "content/public/browser/browser_context.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/permission_manager.h"
-#include "content/public/browser/permission_type.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/render_process_host_observer.h"
-#include "content/public/browser/storage_partition.h"
-#include "content/public/browser/web_contents.h"
-#include "media/base/cdm_config.h"
-#include "media/base/cdm_factory.h"
-#include "media/base/cdm_promise.h"
-#include "media/base/limits.h"
-
-#if defined(OS_ANDROID)
-#include "content/public/browser/android/provision_fetcher_factory.h"
-#include "content/public/common/renderer_preferences.h"
-#include "media/base/android/android_cdm_factory.h"
-#endif
-
-namespace content {
-
-using media::MediaKeys;
-
-namespace {
-
-#if defined(OS_ANDROID)
-// Android only supports 128-bit key IDs.
-const size_t kAndroidKeyIdBytes = 128 / 8;
-#endif
-
-// The ID used in this class is a concatenation of |render_frame_id| and
-// |cdm_id|, i.e. (render_frame_id << 32) + cdm_id.
-
-uint64_t GetId(int render_frame_id, int cdm_id) {
- return (static_cast<uint64_t>(render_frame_id) << 32) +
- static_cast<uint64_t>(cdm_id);
-}
-
-bool IdBelongsToFrame(uint64_t id, int render_frame_id) {
- return (id >> 32) == static_cast<uint64_t>(render_frame_id);
-}
-
-// media::CdmPromiseTemplate implementation backed by a BrowserCdmManager.
-template <typename... T>
-class CdmPromiseInternal : public media::CdmPromiseTemplate<T...> {
- public:
- CdmPromiseInternal(const base::WeakPtr<BrowserCdmManager>& manager,
- int render_frame_id,
- int cdm_id,
- uint32_t promise_id)
- : manager_(manager),
- render_frame_id_(render_frame_id),
- cdm_id_(cdm_id),
- promise_id_(promise_id) {
- DCHECK(manager_);
- }
-
- ~CdmPromiseInternal() final {
- if (!IsPromiseSettled())
- RejectPromiseOnDestruction();
- }
-
- // CdmPromiseTemplate<> implementation.
- void resolve(const T&... result) final;
-
- void reject(MediaKeys::Exception exception,
- uint32_t system_code,
- const std::string& error_message) final {
- MarkPromiseSettled();
- if (manager_) {
- manager_->RejectPromise(render_frame_id_, cdm_id_, promise_id_, exception,
- system_code, error_message);
- }
- }
-
- private:
- using media::CdmPromiseTemplate<T...>::IsPromiseSettled;
- using media::CdmPromiseTemplate<T...>::MarkPromiseSettled;
- using media::CdmPromiseTemplate<T...>::RejectPromiseOnDestruction;
-
- base::WeakPtr<BrowserCdmManager> const manager_;
- const int render_frame_id_;
- const int cdm_id_;
- const uint32_t promise_id_;
-};
-
-template <>
-void CdmPromiseInternal<>::resolve() {
- MarkPromiseSettled();
- if (manager_)
- manager_->ResolvePromise(render_frame_id_, cdm_id_, promise_id_);
-}
-
-template <>
-void CdmPromiseInternal<std::string>::resolve(const std::string& session_id) {
- MarkPromiseSettled();
- if (manager_) {
- manager_->ResolvePromiseWithSession(render_frame_id_, cdm_id_, promise_id_,
- session_id);
- }
-}
-
-typedef CdmPromiseInternal<> SimplePromise;
-typedef CdmPromiseInternal<std::string> NewSessionPromise;
-
-// Render process ID to BrowserCdmManager map.
-typedef std::map<int, BrowserCdmManager*> BrowserCdmManagerMap;
-base::LazyInstance<BrowserCdmManagerMap>::Leaky g_browser_cdm_manager_map =
- LAZY_INSTANCE_INITIALIZER;
-
-// Keeps the BrowserCdmManager alive, and in the global map, for as long as the
-// RenderProcessHost is connected to the child process. This class is a
-// self-owned observer.
-class BrowserCdmManagerProcessWatcher : public RenderProcessHostObserver {
- public:
- BrowserCdmManagerProcessWatcher(
- int render_process_id,
- const scoped_refptr<BrowserCdmManager>& manager)
- : browser_cdm_manager_(manager) {
- RenderProcessHost::FromID(render_process_id)->AddObserver(this);
- CHECK(g_browser_cdm_manager_map.Get()
- .insert(std::make_pair(render_process_id, manager.get()))
- .second);
- }
-
- // RenderProcessHostObserver:
- void RenderProcessExited(RenderProcessHost* host,
- base::TerminationStatus /* status */,
- int /* exit_code */) override {
- RemoveHostObserverAndDestroy(host);
- }
-
- void RenderProcessHostDestroyed(RenderProcessHost* host) override {
- RemoveHostObserverAndDestroy(host);
- }
-
- private:
- void RemoveHostObserverAndDestroy(RenderProcessHost* host) {
- CHECK(g_browser_cdm_manager_map.Get().erase(host->GetID()));
- host->RemoveObserver(this);
- delete this;
- }
-
- const scoped_refptr<BrowserCdmManager> browser_cdm_manager_;
-};
-
-} // namespace
-
-// static
-BrowserCdmManager* BrowserCdmManager::FromProcess(int render_process_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- auto& map = g_browser_cdm_manager_map.Get();
- auto iterator = map.find(render_process_id);
- return (iterator == map.end()) ? nullptr : iterator->second;
-}
-
-BrowserCdmManager::BrowserCdmManager(
- int render_process_id,
- const scoped_refptr<base::TaskRunner>& task_runner)
- : BrowserMessageFilter(CdmMsgStart),
- render_process_id_(render_process_id),
- task_runner_(task_runner),
- weak_ptr_factory_(this) {
- DVLOG(1) << __FUNCTION__ << ": " << render_process_id_;
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- new BrowserCdmManagerProcessWatcher(render_process_id, this);
-
- if (!task_runner_.get()) {
- task_runner_ = BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
- }
-}
-
-BrowserCdmManager::~BrowserCdmManager() {
- DVLOG(1) << __FUNCTION__ << ": " << render_process_id_;
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-}
-
-// Makes sure BrowserCdmManager is always deleted on the Browser UI thread.
-void BrowserCdmManager::OnDestruct() const {
- DVLOG(1) << __FUNCTION__ << ": " << render_process_id_;
- if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- delete this;
- } else {
- BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this);
- }
-}
-
-base::TaskRunner* BrowserCdmManager::OverrideTaskRunnerForMessage(
- const IPC::Message& message) {
- // Only handles CDM messages.
- if (IPC_MESSAGE_CLASS(message) != CdmMsgStart)
- return NULL;
-
- return task_runner_.get();
-}
-
-bool BrowserCdmManager::OnMessageReceived(const IPC::Message& msg) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(BrowserCdmManager, msg)
- IPC_MESSAGE_HANDLER(CdmHostMsg_InitializeCdm, OnInitializeCdm)
- IPC_MESSAGE_HANDLER(CdmHostMsg_SetServerCertificate, OnSetServerCertificate)
- IPC_MESSAGE_HANDLER(CdmHostMsg_CreateSessionAndGenerateRequest,
- OnCreateSessionAndGenerateRequest)
- IPC_MESSAGE_HANDLER(CdmHostMsg_LoadSession, OnLoadSession)
- IPC_MESSAGE_HANDLER(CdmHostMsg_UpdateSession, OnUpdateSession)
- IPC_MESSAGE_HANDLER(CdmHostMsg_CloseSession, OnCloseSession)
- IPC_MESSAGE_HANDLER(CdmHostMsg_RemoveSession, OnRemoveSession)
- IPC_MESSAGE_HANDLER(CdmHostMsg_DestroyCdm, OnDestroyCdm)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-scoped_refptr<MediaKeys> BrowserCdmManager::GetCdm(int render_frame_id,
- int cdm_id) const {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
- const auto& iter = cdm_map_.find(GetId(render_frame_id, cdm_id));
- return iter == cdm_map_.end() ? nullptr : iter->second;
-}
-
-void BrowserCdmManager::RenderFrameDeleted(int render_frame_id) {
- if (!task_runner_->RunsTasksOnCurrentThread()) {
- task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&BrowserCdmManager::RemoveAllCdmForFrame,
- this, render_frame_id));
- return;
- }
- RemoveAllCdmForFrame(render_frame_id);
-}
-
-void BrowserCdmManager::ResolvePromise(int render_frame_id,
- int cdm_id,
- uint32_t promise_id) {
- Send(new CdmMsg_ResolvePromise(render_frame_id, cdm_id, promise_id));
-}
-
-void BrowserCdmManager::ResolvePromiseWithSession(
- int render_frame_id,
- int cdm_id,
- uint32_t promise_id,
- const std::string& session_id) {
- if (session_id.length() > media::limits::kMaxSessionIdLength) {
- RejectPromise(render_frame_id, cdm_id, promise_id,
- MediaKeys::INVALID_ACCESS_ERROR, 0,
- "Session ID is too long.");
- return;
- }
-
- Send(new CdmMsg_ResolvePromiseWithSession(render_frame_id, cdm_id, promise_id,
- session_id));
-}
-
-void BrowserCdmManager::RejectPromise(int render_frame_id,
- int cdm_id,
- uint32_t promise_id,
- MediaKeys::Exception exception,
- uint32_t system_code,
- const std::string& error_message) {
- Send(new CdmMsg_RejectPromise(render_frame_id, cdm_id, promise_id, exception,
- system_code, error_message));
-}
-
-media::CdmFactory* BrowserCdmManager::GetCdmFactory() {
- if (!cdm_factory_) {
- // Create a new CdmFactory.
- cdm_factory_ = GetContentClient()->browser()->CreateCdmFactory();
-
-#if defined(OS_ANDROID)
- if (!cdm_factory_) {
- // Obtain http request context for the current render process.
- net::URLRequestContextGetter* context_getter =
- BrowserContext::GetDefaultStoragePartition(
- RenderProcessHost::FromID(render_process_id_)->
- GetBrowserContext())->GetURLRequestContext();
- DCHECK(context_getter);
-
- cdm_factory_.reset(new media::AndroidCdmFactory(
- base::Bind(&CreateProvisionFetcher, context_getter)));
- }
-#endif
- }
-
- return cdm_factory_.get();
-}
-
-void BrowserCdmManager::OnSessionMessage(int render_frame_id,
- int cdm_id,
- const std::string& session_id,
- MediaKeys::MessageType message_type,
- const std::vector<uint8_t>& message) {
- Send(new CdmMsg_SessionMessage(render_frame_id, cdm_id, session_id,
- message_type, message));
-}
-
-void BrowserCdmManager::OnSessionClosed(int render_frame_id,
- int cdm_id,
- const std::string& session_id) {
- Send(new CdmMsg_SessionClosed(render_frame_id, cdm_id, session_id));
-}
-
-void BrowserCdmManager::OnSessionKeysChange(int render_frame_id,
- int cdm_id,
- const std::string& session_id,
- bool has_additional_usable_key,
- media::CdmKeysInfo keys_info) {
- std::vector<media::CdmKeyInformation> key_info_vector;
- for (auto* key_info : keys_info)
- key_info_vector.push_back(*key_info);
- Send(new CdmMsg_SessionKeysChange(render_frame_id, cdm_id, session_id,
- has_additional_usable_key,
- key_info_vector));
-}
-
-void BrowserCdmManager::OnSessionExpirationUpdate(
- int render_frame_id,
- int cdm_id,
- const std::string& session_id,
- const base::Time& new_expiry_time) {
- Send(new CdmMsg_SessionExpirationUpdate(render_frame_id, cdm_id, session_id,
- new_expiry_time));
-}
-
-// Use a weak pointer here instead of |this| to avoid circular references.
-#define BROWSER_CDM_MANAGER_CB(func, ...) \
- base::Bind(&BrowserCdmManager::func, weak_ptr_factory_.GetWeakPtr(), \
- render_frame_id, cdm_id, ##__VA_ARGS__)
-
-void BrowserCdmManager::OnInitializeCdm(
- int render_frame_id,
- int cdm_id,
- uint32_t promise_id,
- const CdmHostMsg_InitializeCdm_Params& params) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
- DCHECK(!GetCdm(render_frame_id, cdm_id));
-
- std::unique_ptr<SimplePromise> promise(new SimplePromise(
- weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
-
- if (params.key_system.size() > media::limits::kMaxKeySystemLength) {
- NOTREACHED() << "Invalid key system: " << params.key_system;
- promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "Invalid key system.");
- return;
- }
-
- if (!GetCdmFactory()) {
- NOTREACHED() << "CDM not supported.";
- promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "CDM not supported.");
- return;
- }
-
- // The render process makes sure |allow_distinctive_identifier| and
- // |allow_persistent_state| are true. See RenderCdmFactory::Create().
- // TODO(xhwang): Pass |allow_distinctive_identifier| and
- // |allow_persistent_state| from the render process.
- media::CdmConfig cdm_config;
- cdm_config.allow_distinctive_identifier = true;
- cdm_config.allow_persistent_state = true;
- cdm_config.use_hw_secure_codecs = params.use_hw_secure_codecs;
-
- GetCdmFactory()->Create(
- params.key_system, params.security_origin, cdm_config,
- BROWSER_CDM_MANAGER_CB(OnSessionMessage),
- BROWSER_CDM_MANAGER_CB(OnSessionClosed),
- BROWSER_CDM_MANAGER_CB(OnSessionKeysChange),
- BROWSER_CDM_MANAGER_CB(OnSessionExpirationUpdate),
- BROWSER_CDM_MANAGER_CB(OnCdmCreated, params.security_origin,
- base::Passed(&promise)));
-}
-
-void BrowserCdmManager::OnSetServerCertificate(
- int render_frame_id,
- int cdm_id,
- uint32_t promise_id,
- const std::vector<uint8_t>& certificate) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-
- std::unique_ptr<SimplePromise> promise(new SimplePromise(
- weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
-
- scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
- if (!cdm) {
- promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
- return;
- }
-
- if (certificate.empty()) {
- promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "Empty certificate.");
- return;
- }
-
- cdm->SetServerCertificate(certificate, std::move(promise));
-}
-
-void BrowserCdmManager::OnCreateSessionAndGenerateRequest(
- const CdmHostMsg_CreateSessionAndGenerateRequest_Params& params) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-
- int render_frame_id = params.render_frame_id;
- int cdm_id = params.cdm_id;
- const std::vector<uint8_t>& init_data = params.init_data;
- std::unique_ptr<NewSessionPromise> promise(
- new NewSessionPromise(weak_ptr_factory_.GetWeakPtr(), render_frame_id,
- cdm_id, params.promise_id));
-
- if (init_data.size() > media::limits::kMaxInitDataLength) {
- LOG(WARNING) << "InitData for ID: " << cdm_id
- << " too long: " << init_data.size();
- promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "Init data too long.");
- return;
- }
-#if defined(OS_ANDROID)
- // 'webm' initData is a single key ID. On Android the length is restricted.
- if (params.init_data_type == INIT_DATA_TYPE_WEBM &&
- init_data.size() != kAndroidKeyIdBytes) {
- promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0,
- "'webm' initData is not the correct length.");
- return;
- }
-#endif
-
- media::EmeInitDataType eme_init_data_type;
- switch (params.init_data_type) {
- case INIT_DATA_TYPE_WEBM:
- eme_init_data_type = media::EmeInitDataType::WEBM;
- break;
-#if defined(USE_PROPRIETARY_CODECS)
- case INIT_DATA_TYPE_CENC:
- eme_init_data_type = media::EmeInitDataType::CENC;
- break;
-#endif
- default:
- NOTREACHED();
- promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0,
- "Invalid init data type.");
- return;
- }
-
- scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
- if (!cdm) {
- DLOG(WARNING) << "No CDM found for: " << render_frame_id << ", " << cdm_id;
- promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
- return;
- }
-
- CheckPermissionStatus(
- render_frame_id, cdm_id,
- base::Bind(&BrowserCdmManager::CreateSessionAndGenerateRequestIfPermitted,
- this, render_frame_id, cdm_id, params.session_type,
- eme_init_data_type, init_data, base::Passed(&promise)));
-}
-
-void BrowserCdmManager::OnLoadSession(
- int render_frame_id,
- int cdm_id,
- uint32_t promise_id,
- media::MediaKeys::SessionType session_type,
- const std::string& session_id) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-
- std::unique_ptr<NewSessionPromise> promise(new NewSessionPromise(
- weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
-
- scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
- if (!cdm) {
- DLOG(WARNING) << "No CDM found for: " << render_frame_id << ", " << cdm_id;
- promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
- return;
- }
-
- CheckPermissionStatus(
- render_frame_id, cdm_id,
- base::Bind(&BrowserCdmManager::LoadSessionIfPermitted,
- this, render_frame_id, cdm_id, session_type,
- session_id, base::Passed(&promise)));
-}
-
-void BrowserCdmManager::OnUpdateSession(int render_frame_id,
- int cdm_id,
- uint32_t promise_id,
- const std::string& session_id,
- const std::vector<uint8_t>& response) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-
- std::unique_ptr<SimplePromise> promise(new SimplePromise(
- weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
-
- scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
- if (!cdm) {
- promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
- return;
- }
-
- if (response.size() > media::limits::kMaxSessionResponseLength) {
- LOG(WARNING) << "Response for ID " << cdm_id
- << " is too long: " << response.size();
- promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "Response too long.");
- return;
- }
-
- if (response.empty()) {
- promise->reject(MediaKeys::INVALID_ACCESS_ERROR, 0, "Response is empty.");
- return;
- }
-
- cdm->UpdateSession(session_id, response, std::move(promise));
-}
-
-void BrowserCdmManager::OnCloseSession(int render_frame_id,
- int cdm_id,
- uint32_t promise_id,
- const std::string& session_id) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-
- std::unique_ptr<SimplePromise> promise(new SimplePromise(
- weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
-
- scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
- if (!cdm) {
- promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
- return;
- }
-
- cdm->CloseSession(session_id, std::move(promise));
-}
-
-void BrowserCdmManager::OnRemoveSession(int render_frame_id,
- int cdm_id,
- uint32_t promise_id,
- const std::string& session_id) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-
- std::unique_ptr<SimplePromise> promise(new SimplePromise(
- weak_ptr_factory_.GetWeakPtr(), render_frame_id, cdm_id, promise_id));
-
- scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
- if (!cdm) {
- promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
- return;
- }
-
- cdm->RemoveSession(session_id, std::move(promise));
-}
-
-void BrowserCdmManager::OnDestroyCdm(int render_frame_id, int cdm_id) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
- RemoveCdm(GetId(render_frame_id, cdm_id));
-}
-
-void BrowserCdmManager::OnCdmCreated(
- int render_frame_id,
- int cdm_id,
- const GURL& security_origin,
- std::unique_ptr<media::SimpleCdmPromise> promise,
- const scoped_refptr<media::MediaKeys>& cdm,
- const std::string& error_message) {
- if (!cdm) {
- DVLOG(1) << "Failed to create CDM: " << error_message;
- promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, error_message);
- return;
- }
-
- uint64_t id = GetId(render_frame_id, cdm_id);
- cdm_map_[id] = cdm;
- cdm_security_origin_map_[id] = security_origin;
- promise->resolve();
-}
-
-void BrowserCdmManager::RemoveAllCdmForFrame(int render_frame_id) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-
- std::vector<uint64_t> ids_to_remove;
- for (const auto& entry : cdm_map_) {
- if (IdBelongsToFrame(entry.first, render_frame_id))
- ids_to_remove.push_back(entry.first);
- }
-
- for (const auto& id_to_remove : ids_to_remove)
- RemoveCdm(id_to_remove);
-}
-
-void BrowserCdmManager::RemoveCdm(uint64_t id) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-
- cdm_map_.erase(id);
- cdm_security_origin_map_.erase(id);
-}
-
-void BrowserCdmManager::CheckPermissionStatus(
- int render_frame_id,
- int cdm_id,
- const PermissionStatusCB& permission_status_cb) {
- // Always called on |task_runner_|, which may not be on the UI thread.
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-
- GURL security_origin;
- std::map<uint64_t, GURL>::const_iterator iter =
- cdm_security_origin_map_.find(GetId(render_frame_id, cdm_id));
- DCHECK(iter != cdm_security_origin_map_.end());
- if (iter != cdm_security_origin_map_.end())
- security_origin = iter->second;
-
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&BrowserCdmManager::CheckPermissionStatusOnUIThread, this,
- render_frame_id, security_origin, permission_status_cb));
- } else {
- CheckPermissionStatusOnUIThread(render_frame_id, security_origin,
- permission_status_cb);
- }
-}
-
-// Note: This function runs on the UI thread, which may be different from
-// |task_runner_|. Be careful about thread safety!
-void BrowserCdmManager::CheckPermissionStatusOnUIThread(
- int render_frame_id,
- const GURL& security_origin,
- const base::Callback<void(bool)>& permission_status_cb) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- RenderFrameHost* rfh =
- RenderFrameHost::FromID(render_process_id_, render_frame_id);
- WebContents* web_contents = WebContents::FromRenderFrameHost(rfh);
- PermissionManager* permission_manager =
- web_contents->GetBrowserContext()->GetPermissionManager();
- if (!permission_manager) {
- permission_status_cb.Run(false);
- return;
- }
-
- blink::mojom::PermissionStatus permission_status =
- permission_manager->GetPermissionStatus(
- PermissionType::PROTECTED_MEDIA_IDENTIFIER, security_origin,
- web_contents->GetLastCommittedURL().GetOrigin());
-
- bool allowed = (permission_status == blink::mojom::PermissionStatus::GRANTED);
- if (!task_runner_->RunsTasksOnCurrentThread()) {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(permission_status_cb, allowed));
- } else {
- permission_status_cb.Run(allowed);
- }
-}
-
-void BrowserCdmManager::CreateSessionAndGenerateRequestIfPermitted(
- int render_frame_id,
- int cdm_id,
- media::MediaKeys::SessionType session_type,
- media::EmeInitDataType init_data_type,
- const std::vector<uint8_t>& init_data,
- std::unique_ptr<media::NewSessionCdmPromise> promise,
- bool permission_was_allowed) {
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-
- if (!permission_was_allowed) {
- promise->reject(MediaKeys::NOT_SUPPORTED_ERROR, 0, "Permission denied.");
- return;
- }
-
- scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
- if (!cdm) {
- promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
- return;
- }
-
- cdm->CreateSessionAndGenerateRequest(session_type, init_data_type, init_data,
- std::move(promise));
-}
-
-void BrowserCdmManager::LoadSessionIfPermitted(
- int render_frame_id,
- int cdm_id,
- media::MediaKeys::SessionType session_type,
- const std::string& session_id,
- std::unique_ptr<media::NewSessionCdmPromise> promise,
- bool permission_was_allowed) {
- DCHECK_NE(media::MediaKeys::SessionType::TEMPORARY_SESSION, session_type);
- DCHECK(task_runner_->RunsTasksOnCurrentThread());
-
- if (!permission_was_allowed) {
- promise->reject(MediaKeys::NOT_SUPPORTED_ERROR, 0, "Permission denied.");
- return;
- }
-
- scoped_refptr<MediaKeys> cdm = GetCdm(render_frame_id, cdm_id);
- if (!cdm) {
- promise->reject(MediaKeys::INVALID_STATE_ERROR, 0, "CDM not found.");
- return;
- }
-
- cdm->LoadSession(session_type, session_id, std::move(promise));
-}
-
-} // namespace content

Powered by Google App Engine
This is Rietveld 408576698