blob: 02ae2310117da91a67eb91d047733c093d49f2bd [file] [log] [blame]
// Copyright 2016 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_registry_impl.h"
#include <stddef.h>
#include "base/logging.h"
#include "content/public/common/cdm_info.h"
#include "content/public/common/content_client.h"
#include "media/base/key_system_names.h"
namespace content {
namespace {
bool MatchKeySystem(const CdmInfo& cdm_info, const std::string& key_system) {
return cdm_info.key_system == key_system ||
(cdm_info.supports_sub_key_systems &&
media::IsSubKeySystemOf(key_system, cdm_info.key_system));
}
} // namespace
// static
CdmRegistry* CdmRegistry::GetInstance() {
return CdmRegistryImpl::GetInstance();
}
// static
CdmRegistryImpl* CdmRegistryImpl::GetInstance() {
static CdmRegistryImpl* registry = new CdmRegistryImpl();
return registry;
}
CdmRegistryImpl::CdmRegistryImpl() {}
CdmRegistryImpl::~CdmRegistryImpl() {}
void CdmRegistryImpl::Init() {
base::AutoLock auto_lock(lock_);
// Let embedders register CDMs.
GetContentClient()->AddContentDecryptionModules(&cdms_, nullptr);
}
void CdmRegistryImpl::RegisterCdm(const CdmInfo& info) {
base::AutoLock auto_lock(lock_);
// Always register new CDMs at the end of the list, so that the behavior is
// consistent across the browser process's lifetime. For example, we'll always
// use the same registered CDM for a given key system. This also means that
// some later registered CDMs (component updated) will not be used until
// browser restart, which is fine in most cases.
cdms_.push_back(info);
}
std::unique_ptr<CdmInfo> CdmRegistryImpl::GetCdmInfo(
const std::string& key_system,
CdmInfo::Robustness robustness) {
base::AutoLock auto_lock(lock_);
for (const auto& cdm : cdms_) {
if (cdm.robustness == robustness && MatchKeySystem(cdm, key_system))
return std::make_unique<CdmInfo>(cdm);
}
return nullptr;
}
bool CdmRegistryImpl::FinalizeCdmCapability(
const std::string& key_system,
CdmInfo::Robustness robustness,
absl::optional<media::CdmCapability> cdm_capability) {
base::AutoLock auto_lock(lock_);
auto itr = cdms_.begin();
for (; itr != cdms_.end(); itr++) {
if (itr->robustness == robustness && MatchKeySystem(*itr, key_system))
break;
}
if (itr == cdms_.end()) {
DVLOG(1) << __func__ << ": Cannot find CdmInfo to finalize";
return false;
}
if (itr->capability) {
DVLOG(1) << __func__ << ": CdmCapability already finalized";
return false;
}
if (!cdm_capability) {
DVLOG(1) << __func__ << ": No CdmCapability supported. Removing CdmInfo!";
cdms_.erase(itr);
return false;
}
itr->capability = cdm_capability.value();
return true;
}
const std::vector<CdmInfo>& CdmRegistryImpl::GetRegisteredCdms() {
base::AutoLock auto_lock(lock_);
return cdms_;
}
void CdmRegistryImpl::ResetForTesting() {
base::AutoLock auto_lock(lock_);
cdms_.clear();
}
} // namespace content