// Copyright 2016 The Chromium Authors
// 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/check.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "base/strings/string_split.h"
#include "base/task/bind_post_task.h"
#include "base/types/expected.h"
#include "base/types/optional_util.h"
#include "build/build_config.h"
#include "content/public/common/cdm_info.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "media/base/cdm_capability.h"
#include "media/base/key_system_capability.h"
#include "media/base/key_system_names.h"
#include "media/base/key_systems.h"
#include "media/base/media_switches.h"
#include "media/base/video_codecs.h"
#include "media/media_buildflags.h"
#include "media/mojo/buildflags.h"

#if BUILDFLAG(IS_ANDROID)
#include "content/browser/media/key_system_support_android.h"
#include "media/base/android/media_drm_bridge.h"
#endif

#if BUILDFLAG(IS_WIN)
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/media/key_system_support_win.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#endif

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));
}

// Reports whether the software secure CDM is available.
void ReportSoftwareSecureCdmAvailableUMA(const std::string& key_system,
                                         bool available) {
  // Use GetKeySystemNameForUMA() without specifying `use_hw_secure_codecs` for
  // backward compatibility.
  base::UmaHistogramBoolean("Media.EME." +
                                media::GetKeySystemNameForUMA(key_system) +
                                ".LibraryCdmAvailable",
                            available);
}

constexpr media::VideoCodec kVideoCodecsToReportToUma[] = {
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
    media::VideoCodec::kH264,
#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
    media::VideoCodec::kHEVC,
#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
    media::VideoCodec::kDolbyVision,
#endif  // BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION)
#endif  // BUILDFLAG(ENABLE_PLATFORM_HEVC)
#endif  // BUILDFLAG(USE_PROPRIETARY_CODECS)
    media::VideoCodec::kVP9, media::VideoCodec::kAV1};

// Reports the status and capabilities of the hardware secure CDM. Only reported
// once per browser session per `key_system`.
void ReportHardwareSecureCapabilityStatusUMA(
    const std::string& key_system,
    CdmInfo::Status status,
    const media::CdmCapability* hw_secure_capability) {
  // Use a set to track whether the UMA has been reported for `key_system` to
  // make sure we only report once.
  static base::NoDestructor<std::set<std::string>> reported_key_systems;
  if (reported_key_systems->count(key_system)) {
    return;
  }

  reported_key_systems->insert(key_system);

  auto uma_prefix =
      "Media.EME." +
      media::GetKeySystemNameForUMA(key_system, /*use_hw_secure_codecs=*/true);

  // Report whether hardware secure decryption is disabled and if so why.
  base::UmaHistogramEnumeration(uma_prefix + ".CdmInfoStatus", status);

  // When hardware secure decryption is enabled, report whether it is supported.
  if (status == CdmInfo::Status::kEnabled) {
    base::UmaHistogramBoolean(uma_prefix + ".Support", hw_secure_capability);
    // When supported, report whether a particular video codec is supported.
    if (hw_secure_capability) {
      const auto& video_codecs = hw_secure_capability->video_codecs;
      for (const auto& video_codec : kVideoCodecsToReportToUma) {
        bool is_supported = video_codecs.count(video_codec);
        base::UmaHistogramBoolean(
            uma_prefix + ".Support." + media::GetCodecNameForUMA(video_codec),
            is_supported);
      }
    }
  }
}

// Reports the status of the hardware secure capability query. Only reported
// once per browser session per `key_system`.
void ReportHardwareSecureCapabilityQueryStatusUMA(
    const std::string& key_system,
    media::CdmCapabilityQueryStatus capability_query_status) {
  // Use a set to track whether the UMA has been reported for `key_system` to
  // make sure we only report once.
  static base::NoDestructor<std::set<std::string>> reported_key_systems;
  if (reported_key_systems->count(key_system)) {
    return;
  }

  reported_key_systems->insert(key_system);

  auto uma_prefix =
      "Media.EME." +
      media::GetKeySystemNameForUMA(key_system, /*use_hw_secure_codecs=*/true);
  base::UmaHistogramEnumeration(uma_prefix + ".CdmCapabilityQueryStatus",
                                capability_query_status);
}

bool IsEnabled(CdmInfo::Status status) {
  return status == CdmInfo::Status::kEnabled ||
         status == CdmInfo::Status::kCommandLineOverridden;
}

// Returns a CdmCapability with codecs specified on command line. Returns null
// if kOverrideHardwareSecureCodecsForTesting was not specified or not valid
// codecs specified.
std::optional<media::CdmCapability>
GetHardwareSecureCapabilityOverriddenFromCommandLine() {
  auto* command_line = base::CommandLine::ForCurrentProcess();
  if (!command_line || !command_line->HasSwitch(
                           switches::kOverrideHardwareSecureCodecsForTesting)) {
    return std::nullopt;
  }

  auto overridden_codecs_string = command_line->GetSwitchValueASCII(
      switches::kOverrideHardwareSecureCodecsForTesting);
  const auto overridden_codecs =
      base::SplitStringPiece(overridden_codecs_string, ",",
                             base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  // As the command line switch does not include profiles, specify {} to
  // indicate that all relevant profiles should be considered supported.
  std::vector<media::AudioCodec> audio_codecs;
  media::CdmCapability::VideoCodecMap video_codecs;
  const media::VideoCodecInfo kAllProfiles;
  const media::VideoCodecInfo kAllProfilesNoClearLead = {{}, false};
  for (const auto& codec : overridden_codecs) {
    if (codec == "vp8") {
      video_codecs.emplace(media::VideoCodec::kVP8, kAllProfiles);
    } else if (codec == "vp9") {
      video_codecs.emplace(media::VideoCodec::kVP9, kAllProfiles);
    } else if (codec == "avc1") {
      video_codecs.emplace(media::VideoCodec::kH264, kAllProfiles);
    } else if (codec == "hevc") {
      video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfiles);
    } else if (codec == "dolbyvision") {
      video_codecs.emplace(media::VideoCodec::kDolbyVision, kAllProfiles);
    } else if (codec == "av01") {
      video_codecs.emplace(media::VideoCodec::kAV1, kAllProfiles);
    } else if (codec == "vp8-no-clearlead") {
      video_codecs.emplace(media::VideoCodec::kVP8, kAllProfilesNoClearLead);
    } else if (codec == "vp9-no-clearlead") {
      video_codecs.emplace(media::VideoCodec::kVP9, kAllProfilesNoClearLead);
    } else if (codec == "avc1-no-clearlead") {
      video_codecs.emplace(media::VideoCodec::kH264, kAllProfilesNoClearLead);
    } else if (codec == "hevc-no-clearlead") {
      video_codecs.emplace(media::VideoCodec::kHEVC, kAllProfilesNoClearLead);
    } else if (codec == "dolbyvision-no-clearlead") {
      video_codecs.emplace(media::VideoCodec::kDolbyVision,
                           kAllProfilesNoClearLead);
    } else if (codec == "av01-no-clearlead") {
      video_codecs.emplace(media::VideoCodec::kAV1, kAllProfilesNoClearLead);
    } else if (codec == "mp4a") {
      audio_codecs.push_back(media::AudioCodec::kAAC);
    } else if (codec == "vorbis") {
      audio_codecs.push_back(media::AudioCodec::kVorbis);
    } else {
      DVLOG(1) << "Unsupported codec specified on command line: " << codec;
    }
  }

  if (video_codecs.empty()) {
    DVLOG(1) << "No codec codec specified on command line";
    return std::nullopt;
  }

  // Overridden codecs assume CENC and temporary session support.
  // The EncryptedMediaSupportedTypesWidevineHwSecureTest tests depend
  // on 'cbcs' not being supported.
  return media::CdmCapability(std::move(audio_codecs), std::move(video_codecs),
                              {media::EncryptionScheme::kCenc},
                              {media::CdmSessionType::kTemporary},
                              base::Version("0.1.0.0"));
}

#if BUILDFLAG(IS_WIN)
bool IsMediaFoundationHardwareSecurityDisabledByGpuFeature() {
  auto* gpu_data_manager = GpuDataManagerImpl::GetInstance();
  DCHECK(gpu_data_manager->IsGpuFeatureInfoAvailable());
  return gpu_data_manager->GetGpuFeatureInfo().IsWorkaroundEnabled(
      gpu::DISABLE_MEDIA_FOUNDATION_HARDWARE_SECURITY);
}

bool IsGpuHardwareCompositionDisabled() {
  auto* gpu_data_manager = GpuDataManagerImpl::GetInstance();
  return gpu_data_manager->IsGpuCompositingDisabled() ||
         !gpu_data_manager->GetGPUInfo().overlay_info.direct_composition;
}

bool IsGpuSoftwareEmulated() {
  auto* gpu_data_manager = GpuDataManagerImpl::GetInstance();
  const bool is_gpu_software_emulated =
      gpu_data_manager->GetGPUInfo().active_gpu().IsSoftwareRenderer();
  return is_gpu_software_emulated;
}
#endif  // BUILDFLAG(IS_WIN)

}  // namespace

// static
CdmRegistry* CdmRegistry::GetInstance() {
  return CdmRegistryImpl::GetInstance();
}

// static
CdmRegistryImpl* CdmRegistryImpl::GetInstance() {
  static CdmRegistryImpl* registry = new CdmRegistryImpl();
  return registry;
}

CdmRegistryImpl::CdmRegistryImpl() {
#if BUILDFLAG(IS_WIN)
  GpuDataManagerImpl::GetInstance()->AddObserver(this);
#endif  // BUILDFLAG(IS_WIN)
}

CdmRegistryImpl::~CdmRegistryImpl() {
#if BUILDFLAG(IS_WIN)
  GpuDataManagerImpl::GetInstance()->RemoveObserver(this);
#endif  // BUILDFLAG(IS_WIN)
}

void CdmRegistryImpl::Init() {
  DVLOG(1) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Let embedders register CDMs.
  GetContentClient()->AddContentDecryptionModules(&cdms_, nullptr);
}

void CdmRegistryImpl::RegisterCdm(const CdmInfo& info) {
  DVLOG(1) << __func__ << ": key_system=" << info.key_system
           << ", robustness=" << info.robustness
           << ", status=" << static_cast<int>(info.status);
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // 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);

  // Reset cached `key_system_capabilities_` to avoid notifying new observers
  // with the old capabilities and then update them again with new ones.
  // This could cause notifying observers with the same capabilities multiple
  // times, which is okay.
  key_system_capabilities_.reset();

  // If there are `key_system_capabilities_update_callbacks_` registered,
  // finalize key system capabilities and notify the callbacks. Otherwise  we'll
  // finalize key system capabilities in `ObserveKeySystemCapabilities()`.
  if (!key_system_capabilities_update_callbacks_.empty()) {
    FinalizeKeySystemCapabilities();
  }
}

void CdmRegistryImpl::SetHardwareSecureCdmStatus(CdmInfo::Status status) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(status != CdmInfo::Status::kUninitialized &&
         status != CdmInfo::Status::kEnabled &&
         status != CdmInfo::Status::kCommandLineOverridden);

  bool updated = false;
  for (auto& cdm_info : cdms_) {
    if (cdm_info.robustness == CdmInfo::Robustness::kHardwareSecure) {
      cdm_info.status = status;
      updated = true;
    }
  }

  if (!updated) {
    DVLOG(1) << "No hardware secure CDMs to update";
    return;
  }

  key_system_capabilities_.reset();

  // If there are `key_system_capabilities_update_callbacks_` registered,
  // finalize key system capabilities and notify the callbacks. Otherwise  we'll
  // finalize key system capabilities in `ObserveKeySystemCapabilities()`.
  if (!key_system_capabilities_update_callbacks_.empty()) {
    FinalizeKeySystemCapabilities();
  }
}

void CdmRegistryImpl::OnGpuInfoUpdate() {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

#if BUILDFLAG(IS_WIN)
  if (IsGpuHardwareCompositionDisabled()) {
    SetHardwareSecureCdmStatus(CdmInfo::Status::kGpuCompositionDisabled);
  }
#endif  // BUILDFLAG(IS_WIN)
}

const std::vector<CdmInfo>& CdmRegistryImpl::GetRegisteredCdms() const {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  return cdms_;
}

std::unique_ptr<CdmInfo> CdmRegistryImpl::GetCdmInfo(
    const std::string& key_system,
    CdmInfo::Robustness robustness) const {
  DVLOG(2) << __func__ << ": key_system=" << key_system
           << ", robustness=" << robustness;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  for (const auto& cdm : cdms_) {
    if (cdm.robustness == robustness && MatchKeySystem(cdm, key_system)) {
      return std::make_unique<CdmInfo>(cdm);
    }
  }

  return nullptr;
}

base::CallbackListSubscription CdmRegistryImpl::ObserveKeySystemCapabilities(
    bool allow_hw_secure_capability_check,
    KeySystemCapabilitiesUpdateCB cb) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  auto subscription = key_system_capabilities_update_callbacks_.Add(cb);

  // Re-trigger Hardware secure capability check when we encounter the first
  // observer that allows the check.
  if (allow_hw_secure_capability_check && !allow_hw_secure_capability_check_) {
    allow_hw_secure_capability_check_ = true;
    key_system_capabilities_.reset();
    pending_lazy_initializations_.clear();
    weak_ptr_factory_.InvalidateWeakPtrs();
    FinalizeKeySystemCapabilities();
    return subscription;
  }

  if (!pending_lazy_initializations_.empty()) {
    // Lazy initializing some key systems. All callbacks will be notified when
    // that's finished.
    return subscription;
  }

  if (key_system_capabilities_.has_value()) {
    cb.Run(key_system_capabilities_.value());
    return subscription;
  }

  FinalizeKeySystemCapabilities();
  return subscription;
}

std::pair<std::optional<media::CdmCapability>, CdmInfo::Status>
CdmRegistryImpl::GetCapability(const std::string& key_system,
                               CdmInfo::Robustness robustness) {
  DVLOG(2) << __func__ << ": key_system=" << key_system
           << ", robustness=" << robustness;
  using Status = CdmInfo::Status;

  if (robustness == CdmInfo::Robustness::kHardwareSecure) {
#if !BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
    if (!media::IsHardwareSecureDecryptionEnabled()) {
      DVLOG(1) << "Hardware secure decryption disabled";
      return {std::nullopt, Status::kHardwareSecureDecryptionDisabled};
    }
#endif  // !BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)

    // Secure codecs override takes precedence over other checks.
    auto overridden_capability =
        GetHardwareSecureCapabilityOverriddenFromCommandLine();
    if (overridden_capability) {
      DVLOG(1) << "Hardware secure codecs overridden from command line";
      return {overridden_capability, Status::kCommandLineOverridden};
    }

    // Hardware secure video codecs need hardware video decoder support.
    // TODO(xhwang): Make sure this check is as close as possible to the check
    // in the render process. For example, also check check GPU features like
    // GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE.
    auto* command_line = base::CommandLine::ForCurrentProcess();
    if (command_line &&
        command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
      DVLOG(1) << "Hardware security not supported because accelerated video "
                  "decode disabled";
      return {std::nullopt, Status::kAcceleratedVideoDecodeDisabled};
    }

#if BUILDFLAG(IS_WIN)
    // Check if the GPU is disabled from gpu/config/gpu_driver_bug_list.json.
    if (IsMediaFoundationHardwareSecurityDisabledByGpuFeature()) {
      DVLOG(1) << "Hardware security not supported: GPU workarounds";
      return {std::nullopt, Status::kGpuFeatureDisabled};
    }

    if (IsGpuHardwareCompositionDisabled()) {
      DVLOG(1) << "Hardware security not supported: GPU composition disabled";
      return {std::nullopt, Status::kGpuCompositionDisabled};
    }

    // Due to the bugs (crbug.com/41496376 and crbug.com/41497095),
    // `disable_media_foundation_hardware_security` workaround flag cannot be
    // enabled for the vendor ID 0x0000 and 0x1414. All software emulated GPUs
    // are considered as disabled for the media foundation hardware security.
    if (IsGpuSoftwareEmulated()) {
      DVLOG(1)
          << "Hardware security not supported: software emulated GPU enabled";
      return {std::nullopt, Status::kDisabledBySoftwareEmulatedGpu};
    }
#endif  // BUILDFLAG(IS_WIN)
  }

  auto cdm_info = GetCdmInfo(key_system, robustness);
  if (!cdm_info) {
    DVLOG(1) << "No " << robustness << " decryption CDM registered for "
             << key_system;
    return {std::nullopt, Status::kEnabled};
  }

  DCHECK(!(cdm_info->status == Status::kUninitialized && cdm_info->capability))
      << "Capability for " << robustness << " " << key_system
      << " should not have value if uninitialized.";

  return {cdm_info->capability, cdm_info->status};
}

std::pair<std::optional<media::CdmCapability>, CdmInfo::Status>
CdmRegistryImpl::GetFinalCapability(const std::string& key_system,
                                    CdmInfo::Robustness robustness) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // `status` could be kUninitialized if HW secure capability checking is not
  // allowed.
  const auto [capability, status] = GetCapability(key_system, robustness);

  return {IsEnabled(status) ? capability : std::nullopt, status};
}

void CdmRegistryImpl::FinalizeKeySystemCapabilities() {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!key_system_capabilities_.has_value());

  // Abort existing pending LazyInitializeHardwareSecureCapability() operations
  // to avoid updating the observer twice.
  pending_lazy_initializations_.clear();
  weak_ptr_factory_.InvalidateWeakPtrs();

  // Get the set of supported key systems in case two CDMs are registered with
  // the same key system and robustness; this also avoids updating `cdms_`
  // while iterating through it.
  std::set<std::string> supported_key_systems = GetSupportedKeySystems();

  // Attempt to finalize capabilities for all key systems.
  for (const auto& key_system : supported_key_systems) {
    for (const auto robustness : {CdmInfo::Robustness::kSoftwareSecure,
                                  CdmInfo::Robustness::kHardwareSecure}) {
      AttemptToFinalizeKeySystemCapability(key_system, robustness);
    }
  }

  // If not empty, we'll handle it in OnCapabilityInitialized().
  if (pending_lazy_initializations_.empty()) {
    UpdateAndNotifyKeySystemCapabilities();
  }
}

void CdmRegistryImpl::AttemptToFinalizeKeySystemCapability(
    const std::string& key_system,
    CdmInfo::Robustness robustness) {
  auto cdm_info = GetCdmInfo(key_system, robustness);
  if (!cdm_info) {
    DVLOG(1) << "No " << robustness << " CDM registered for " << key_system;
    return;
  }

  if (cdm_info->status != CdmInfo::Status::kUninitialized) {
    DVLOG(1) << robustness << " capability already finalized for "
             << key_system;
    return;
  }

  if (robustness == CdmInfo::Robustness::kHardwareSecure &&
      !allow_hw_secure_capability_check_) {
    DVLOG(1) << robustness
             << " Not allowed to get hardware secure capability for "
             << key_system;
    return;
  }

  const auto [capability, status] = GetCapability(key_system, robustness);
  if (status != CdmInfo::Status::kUninitialized) {
    media::CdmCapabilityOrStatus cdm_capability_or_status =
        base::unexpected(media::CdmCapabilityQueryStatus::kUnknown);
    if (capability.has_value()) {
      cdm_capability_or_status = std::move(capability.value());
    }
    FinalizeCapability(key_system, robustness, cdm_capability_or_status,
                       status);
    return;
  }

  // Needs lazy initialize. Use base::BindPostTaskToCurrentDefault() to force a
  // post.
  pending_lazy_initializations_.insert({key_system, robustness});
  LazyInitializeCapability(
      key_system, robustness,
      base::BindPostTaskToCurrentDefault(base::BindOnce(
          &CdmRegistryImpl::OnCapabilityInitialized,
          weak_ptr_factory_.GetWeakPtr(), key_system, robustness)));
}

// TODO(xhwang): Find a way to register this as callbacks so we don't have to
// hardcode platform-specific logic here.
void CdmRegistryImpl::LazyInitializeCapability(
    const std::string& key_system,
    CdmInfo::Robustness robustness,
    media::CdmCapabilityCB cdm_capability_cb) {
  DVLOG(2) << __func__ << ": key_system=" << key_system
           << ", robustness=" << robustness;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (capability_cb_for_testing_) {
    capability_cb_for_testing_.Run(key_system, robustness,
                                   std::move(cdm_capability_cb));
    return;
  }

#if BUILDFLAG(IS_WIN)
  if (robustness == CdmInfo::Robustness::kHardwareSecure) {
    auto cdm_info =
        GetCdmInfo(key_system, CdmInfo::Robustness::kHardwareSecure);
    DCHECK(cdm_info && !cdm_info->capability);
    GetMediaFoundationServiceCdmCapability(
        key_system, cdm_info->type, cdm_info->path,
        /*is_hw_secure=*/true, std::move(cdm_capability_cb));
  } else {
    // kSoftwareSecure should have been determined from the manifest.
    std::move(cdm_capability_cb)
        .Run(base::unexpected(media::CdmCapabilityQueryStatus::kUnknown));
  }
#elif BUILDFLAG(IS_ANDROID)
  GetAndroidCdmCapability(key_system, robustness, std::move(cdm_capability_cb));
#else
  std::move(cdm_capability_cb)
      .Run(base::unexpected(media::CdmCapabilityQueryStatus::kUnknown));
#endif  // BUILDFLAG(IS_WIN)
}

void CdmRegistryImpl::OnCapabilityInitialized(
    const std::string& key_system,
    const CdmInfo::Robustness robustness,
    media::CdmCapabilityOrStatus cdm_capability_or_status) {
  DVLOG(1) << __func__ << ": key_system=" << key_system
           << ", robustness=" << robustness << ", cdm_capability_or_status="
           << cdm_capability_or_status.ToString();
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(pending_lazy_initializations_.count({key_system, robustness}));

  // Report the status of the hardware secure capability query.
  if (robustness == CdmInfo::Robustness::kHardwareSecure) {
    ReportHardwareSecureCapabilityQueryStatusUMA(
        key_system, cdm_capability_or_status.has_value()
                        ? media::CdmCapabilityQueryStatus::kSuccess
                        : cdm_capability_or_status.error());
  }

  FinalizeCapability(key_system, robustness,
                     std::move(cdm_capability_or_status),
                     CdmInfo::Status::kEnabled);

  pending_lazy_initializations_.erase({key_system, robustness});
  if (pending_lazy_initializations_.empty()) {
    UpdateAndNotifyKeySystemCapabilities();
  }
}

void CdmRegistryImpl::FinalizeCapability(
    const std::string& key_system,
    const CdmInfo::Robustness robustness,
    media::CdmCapabilityOrStatus cdm_capability_or_status,
    CdmInfo::Status status) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(status != CdmInfo::Status::kUninitialized);

  auto itr = cdms_.begin();
  for (; itr != cdms_.end(); itr++) {
    if (itr->robustness == robustness && MatchKeySystem(*itr, key_system)) {
      break;
    }
  }

  if (itr == cdms_.end()) {
    DLOG(ERROR) << __func__ << ": Cannot find CdmInfo to finalize for "
                << key_system << " with robustness " << robustness;
    return;
  }

  if (itr->status != CdmInfo::Status::kUninitialized) {
    DLOG(ERROR) << __func__ << ": CdmCapability already finalized for "
                << key_system << " with robustness " << robustness;
    return;
  }

  itr->status = status;
  if (cdm_capability_or_status.has_value()) {
    itr->capability = std::move(cdm_capability_or_status).value();
    itr->capability_query_status = std::nullopt;
  } else {
    itr->capability = std::nullopt;
    itr->capability_query_status = std::move(cdm_capability_or_status).error();
  }
}

void CdmRegistryImpl::UpdateAndNotifyKeySystemCapabilities() {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(pending_lazy_initializations_.empty());

  auto key_system_capabilities = GetKeySystemCapabilities();

  if (key_system_capabilities_.has_value() &&
      key_system_capabilities_.value() == key_system_capabilities) {
    DVLOG(3) << "Same key system capabilities; no need to update";
    return;
  }

  key_system_capabilities_ = key_system_capabilities;
  key_system_capabilities_update_callbacks_.Notify(key_system_capabilities);
}

std::set<std::string> CdmRegistryImpl::GetSupportedKeySystems() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  std::set<std::string> supported_key_systems;
  for (const auto& cdm : cdms_) {
    supported_key_systems.insert(cdm.key_system);
  }

  return supported_key_systems;
}

KeySystemCapabilities CdmRegistryImpl::GetKeySystemCapabilities() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  KeySystemCapabilities key_system_capabilities;

  std::set<std::string> supported_key_systems = GetSupportedKeySystems();
  for (const auto& key_system : supported_key_systems) {
    CdmInfo::Status status;

    // Software secure capability.
    std::optional<media::CdmCapability> sw_cdm_capability;
    std::tie(sw_cdm_capability, status) =
        GetFinalCapability(key_system, CdmInfo::Robustness::kSoftwareSecure);
    ReportSoftwareSecureCdmAvailableUMA(key_system,
                                        sw_cdm_capability != std::nullopt);

    // Hardware secure capability.
    std::optional<media::CdmCapability> hw_cdm_capability;
    std::tie(hw_cdm_capability, status) =
        GetFinalCapability(key_system, CdmInfo::Robustness::kHardwareSecure);
    ReportHardwareSecureCapabilityStatusUMA(
        key_system, status, base::OptionalToPtr(hw_cdm_capability));

    if (sw_cdm_capability || hw_cdm_capability) {
      key_system_capabilities[key_system] = media::KeySystemCapability(
          sw_cdm_capability.has_value()
              ? media::CdmCapabilityOrStatus(sw_cdm_capability.value())
              : base::unexpected(media::CdmCapabilityQueryStatus::kUnknown),
          hw_cdm_capability.has_value()
              ? media::CdmCapabilityOrStatus(hw_cdm_capability.value())
              : base::unexpected(media::CdmCapabilityQueryStatus::kUnknown));
    }
  }

  return key_system_capabilities;
}

void CdmRegistryImpl::SetCapabilityCBForTesting(CapabilityCB cb) {
  capability_cb_for_testing_ = std::move(cb);
}

}  // namespace content
