// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/cdm/cdm_adapter.h"

#include <stddef.h>
#include <iomanip>
#include <memory>
#include <utility>

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/callback_registry.h"
#include "media/base/cdm_initialized_promise.h"
#include "media/base/cdm_key_information.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "media/base/key_systems.h"
#include "media/base/limits.h"
#include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h"
#include "media/base/video_util.h"
#include "media/cdm/cdm_auxiliary_helper.h"
#include "media/cdm/cdm_helpers.h"
#include "media/cdm/cdm_type_conversion.h"
#include "media/cdm/cdm_wrapper.h"
#include "media/media_buildflags.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h"
#include "url/origin.h"

namespace media {

namespace {

// Constants for UMA reporting of file size (in KB) via
// UMA_HISTOGRAM_CUSTOM_COUNTS. Note that the histogram is log-scaled (rather
// than linear).
constexpr int kSizeKBMin = 1;
constexpr int kSizeKBMax = 512 * 1024;  // 512MB
constexpr int kSizeKBBuckets = 100;

// Only support version 1 of Storage Id. However, the "latest" version can also
// be requested.
constexpr uint32_t kRequestLatestStorageIdVersion = 0;
constexpr uint32_t kCurrentStorageIdVersion = 1;
static_assert(kCurrentStorageIdVersion < 0x80000000,
              "Versions 0x80000000 and above are reserved.");

// Verify that OutputProtection types matches those in CDM interface.
// Cannot use conversion function because these are used in bit masks.
// See CdmAdapter::EnableOutputProtection and
// CdmAdapter::OnQueryOutputProtectionStatusDone() below.
#define ASSERT_ENUM_EQ(media_enum, cdm_enum)                              \
  static_assert(                                                          \
      static_cast<int32_t>(media_enum) == static_cast<int32_t>(cdm_enum), \
      "Mismatched enum: " #media_enum " != " #cdm_enum)

ASSERT_ENUM_EQ(OutputProtection::LinkTypes::NONE, cdm::kLinkTypeNone);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::UNKNOWN, cdm::kLinkTypeUnknown);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::INTERNAL, cdm::kLinkTypeInternal);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::VGA, cdm::kLinkTypeVGA);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::HDMI, cdm::kLinkTypeHDMI);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::DVI, cdm::kLinkTypeDVI);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::DISPLAYPORT,
               cdm::kLinkTypeDisplayPort);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::NETWORK, cdm::kLinkTypeNetwork);
ASSERT_ENUM_EQ(OutputProtection::ProtectionType::NONE, cdm::kProtectionNone);
ASSERT_ENUM_EQ(OutputProtection::ProtectionType::HDCP, cdm::kProtectionHDCP);

std::string CdmStatusToString(cdm::Status status) {
  switch (status) {
    case cdm::kSuccess:
      return "kSuccess";
    case cdm::kNoKey:
      return "kNoKey";
    case cdm::kNeedMoreData:
      return "kNeedMoreData";
    case cdm::kDecryptError:
      return "kDecryptError";
    case cdm::kDecodeError:
      return "kDecodeError";
    case cdm::kInitializationError:
      return "kInitializationError";
    case cdm::kDeferredInitialization:
      return "kDeferredInitialization";
  }

  NOTREACHED_NORETURN();
}

inline std::ostream& operator<<(std::ostream& out, cdm::Status status) {
  return out << CdmStatusToString(status);
}

std::string GetHexKeyId(const cdm::InputBuffer_2& buffer) {
  if (buffer.key_id_size == 0)
    return "N/A";

  return base::HexEncode(buffer.key_id, buffer.key_id_size);
}

std::string GetHexMask(uint32_t mask) {
  std::stringstream hex_string;
  hex_string << "0x" << std::setfill('0') << std::setw(8) << std::hex << mask;
  return hex_string.str();
}

void* GetCdmHost(int host_interface_version, void* user_data) {
  if (!host_interface_version || !user_data)
    return nullptr;

  static_assert(
      CheckSupportedCdmHostVersions(cdm::Host_10::kVersion,
                                    cdm::Host_11::kVersion),
      "Mismatch between GetCdmHost() and IsSupportedCdmHostVersion()");

  DCHECK(IsSupportedCdmHostVersion(host_interface_version));

  CdmAdapter* cdm_adapter = static_cast<CdmAdapter*>(user_data);
  DVLOG(1) << "Create CDM Host with version " << host_interface_version;
  switch (host_interface_version) {
    case cdm::Host_10::kVersion:
      return static_cast<cdm::Host_10*>(cdm_adapter);
    case cdm::Host_11::kVersion:
      return static_cast<cdm::Host_11*>(cdm_adapter);
  }
  NOTREACHED_NORETURN() << "Unexpected host interface version "
                        << host_interface_version;
}

void ReportSystemCodeUMA(const std::string& key_system, uint32_t system_code) {
  base::UmaHistogramSparse(
      "Media.EME." +
          GetKeySystemNameForUMA(key_system, /*use_hw_secure_codecs=*/false) +
          ".SystemCode",
      system_code);
}

// These are reported to UMA server. Do not renumber or reuse values.
enum OutputProtectionStatus {
  kQueried = 0,
  kNoExternalLink = 1,
  kAllExternalLinksProtected = 2,
  // Note: Only add new values immediately before this line.
  kStatusCount
};

void ReportOutputProtectionUMA(OutputProtectionStatus status) {
  UMA_HISTOGRAM_ENUMERATION("Media.EME.OutputProtection", status,
                            OutputProtectionStatus::kStatusCount);
}

crash_reporter::CrashKeyString<256> g_origin_crash_key("cdm-origin");
using crash_reporter::ScopedCrashKeyString;

}  // namespace

// static
void CdmAdapter::Create(
    const CdmConfig& cdm_config,
    CreateCdmFunc create_cdm_func,
    std::unique_ptr<CdmAuxiliaryHelper> helper,
    const SessionMessageCB& session_message_cb,
    const SessionClosedCB& session_closed_cb,
    const SessionKeysChangeCB& session_keys_change_cb,
    const SessionExpirationUpdateCB& session_expiration_update_cb,
    CdmCreatedCB cdm_created_cb) {
  DCHECK(!cdm_config.key_system.empty());
  DCHECK(session_message_cb);
  DCHECK(session_closed_cb);
  DCHECK(session_keys_change_cb);
  DCHECK(session_expiration_update_cb);

  scoped_refptr<CdmAdapter> cdm = new CdmAdapter(
      cdm_config, create_cdm_func, std::move(helper), session_message_cb,
      session_closed_cb, session_keys_change_cb, session_expiration_update_cb);

  // |cdm| ownership passed to the promise.
  cdm->Initialize(
      std::make_unique<CdmInitializedPromise>(std::move(cdm_created_cb), cdm));
}

CdmAdapter::CdmAdapter(
    const CdmConfig& cdm_config,
    CreateCdmFunc create_cdm_func,
    std::unique_ptr<CdmAuxiliaryHelper> helper,
    const SessionMessageCB& session_message_cb,
    const SessionClosedCB& session_closed_cb,
    const SessionKeysChangeCB& session_keys_change_cb,
    const SessionExpirationUpdateCB& session_expiration_update_cb)
    : cdm_config_(cdm_config),
      create_cdm_func_(create_cdm_func),
      helper_(std::move(helper)),
      session_message_cb_(session_message_cb),
      session_closed_cb_(session_closed_cb),
      session_keys_change_cb_(session_keys_change_cb),
      session_expiration_update_cb_(session_expiration_update_cb),
      cdm_origin_(helper_->GetCdmOrigin().Serialize()),
      scoped_crash_key_(&g_origin_crash_key, cdm_origin_),
      task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()),
      pool_(new AudioBufferMemoryPool()) {
  DVLOG(1) << __func__;

  DCHECK(!cdm_config.key_system.empty());
  DCHECK(create_cdm_func_);
  DCHECK(helper_);
  DCHECK(session_message_cb_);
  DCHECK(session_closed_cb_);
  DCHECK(session_keys_change_cb_);
  DCHECK(session_expiration_update_cb_);

  helper_->SetFileReadCB(
      base::BindRepeating(&CdmAdapter::OnFileRead, weak_factory_.GetWeakPtr()));
}

CdmAdapter::~CdmAdapter() {
  DVLOG(1) << __func__;

  // Reject any outstanding promises and close all the existing sessions.
  cdm_promise_adapter_.Clear(CdmPromiseAdapter::ClearReason::kDestruction);

  if (audio_init_cb_)
    std::move(audio_init_cb_).Run(false);
  if (video_init_cb_)
    std::move(video_init_cb_).Run(false);
}

CdmWrapper* CdmAdapter::CreateCdmInstance(const std::string& key_system) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT0("media", "CdmAdapter::CreateCdmInstance");

  CdmWrapper* cdm = CdmWrapper::Create(create_cdm_func_, key_system.data(),
                                       key_system.size(), GetCdmHost, this);
  DVLOG(1) << "CDM instance for " + key_system + (cdm ? "" : " could not be") +
                  " created.";

  if (cdm) {
    // The interface version is relatively small. So using normal histogram
    // instead of a sparse histogram is okay. The following DCHECK asserts this.
    DCHECK(cdm->GetInterfaceVersion() <= 30);
    UMA_HISTOGRAM_ENUMERATION("Media.EME.CdmInterfaceVersion",
                              cdm->GetInterfaceVersion(), 30);
  }

  return cdm;
}

void CdmAdapter::Initialize(std::unique_ptr<media::SimpleCdmPromise> promise) {
  DVLOG(1) << __func__;
  TRACE_EVENT0("media", "CdmAdapter::Initialize");

  cdm_.reset(CreateCdmInstance(cdm_config_.key_system));
  if (!cdm_) {
    promise->reject(CdmPromise::Exception::INVALID_STATE_ERROR, 0,
                    "Unable to create CDM.");
    return;
  }

  init_promise_id_ =
      cdm_promise_adapter_.SavePromise(std::move(promise), __func__);

  if (!cdm_->Initialize(cdm_config_.allow_distinctive_identifier,
                        cdm_config_.allow_persistent_state,
                        cdm_config_.use_hw_secure_codecs)) {
    // OnInitialized() will not be called by the CDM, which is the case for
    // CDM interfaces prior to CDM_10.
    OnInitialized(true);
    return;
  }

  // OnInitialized() will be called by the CDM.
}

int CdmAdapter::GetInterfaceVersion() {
  return cdm_->GetInterfaceVersion();
}

void CdmAdapter::SetServerCertificate(
    const std::vector<uint8_t>& certificate,
    std::unique_ptr<SimpleCdmPromise> promise) {
  DVLOG(2) << __func__;
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT0("media", "CdmAdapter::SetServerCertificate");

  if (certificate.size() < limits::kMinCertificateLength ||
      certificate.size() > limits::kMaxCertificateLength) {
    promise->reject(CdmPromise::Exception::TYPE_ERROR, 0,
                    "Incorrect certificate.");
    return;
  }

  uint32_t promise_id =
      cdm_promise_adapter_.SavePromise(std::move(promise), __func__);
  cdm_->SetServerCertificate(promise_id, certificate.data(),
                             certificate.size());
}

void CdmAdapter::GetStatusForPolicy(
    HdcpVersion min_hdcp_version,
    std::unique_ptr<KeyStatusCdmPromise> promise) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT0("media", "CdmAdapter::GetStatusForPolicy");

  uint32_t promise_id =
      cdm_promise_adapter_.SavePromise(std::move(promise), __func__);
  DVLOG(2) << __func__ << ": promise_id = " << promise_id;
  if (!cdm_->GetStatusForPolicy(promise_id,
                                ToCdmHdcpVersion(min_hdcp_version))) {
    DVLOG(1) << __func__ << ": GetStatusForPolicy not supported";
    cdm_promise_adapter_.RejectPromise(
        promise_id, CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0,
        "GetStatusForPolicy not supported.");
  }
}

void CdmAdapter::CreateSessionAndGenerateRequest(
    CdmSessionType session_type,
    EmeInitDataType init_data_type,
    const std::vector<uint8_t>& init_data,
    std::unique_ptr<NewSessionCdmPromise> promise) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT0("media", "CdmAdapter::CreateSessionAndGenerateRequest");

  uint32_t promise_id =
      cdm_promise_adapter_.SavePromise(std::move(promise), __func__);
  DVLOG(2) << __func__ << ": promise_id = " << promise_id;

  cdm_->CreateSessionAndGenerateRequest(
      promise_id, ToCdmSessionType(session_type),
      ToCdmInitDataType(init_data_type), init_data.data(), init_data.size());
}

void CdmAdapter::LoadSession(CdmSessionType session_type,
                             const std::string& session_id,
                             std::unique_ptr<NewSessionCdmPromise> promise) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT1("media", "CdmAdapter::LoadSession", "session_id", session_id);

  uint32_t promise_id =
      cdm_promise_adapter_.SavePromise(std::move(promise), __func__);
  DVLOG(2) << __func__ << ": session_id = " << session_id
           << ", promise_id = " << promise_id;

  cdm_->LoadSession(promise_id, ToCdmSessionType(session_type),
                    session_id.data(), session_id.size());
}

void CdmAdapter::UpdateSession(const std::string& session_id,
                               const std::vector<uint8_t>& response,
                               std::unique_ptr<SimpleCdmPromise> promise) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(!session_id.empty());
  DCHECK(!response.empty());
  TRACE_EVENT1("media", "CdmAdapter::UpdateSession", "session_id", session_id);

  uint32_t promise_id =
      cdm_promise_adapter_.SavePromise(std::move(promise), __func__);
  DVLOG(2) << __func__ << ": session_id = " << session_id
           << ", promise_id = " << promise_id;

  cdm_->UpdateSession(promise_id, session_id.data(), session_id.size(),
                      response.data(), response.size());
}

void CdmAdapter::CloseSession(const std::string& session_id,
                              std::unique_ptr<SimpleCdmPromise> promise) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(!session_id.empty());
  TRACE_EVENT1("media", "CdmAdapter::CloseSession", "session_id", session_id);

  uint32_t promise_id =
      cdm_promise_adapter_.SavePromise(std::move(promise), __func__);
  DVLOG(2) << __func__ << ": session_id = " << session_id
           << ", promise_id = " << promise_id;

  cdm_->CloseSession(promise_id, session_id.data(), session_id.size());
}

void CdmAdapter::RemoveSession(const std::string& session_id,
                               std::unique_ptr<SimpleCdmPromise> promise) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(!session_id.empty());
  TRACE_EVENT1("media", "CdmAdapter::RemoveSession", "session_id", session_id);

  uint32_t promise_id =
      cdm_promise_adapter_.SavePromise(std::move(promise), __func__);
  DVLOG(2) << __func__ << ": session_id = " << session_id
           << ", promise_id = " << promise_id;

  cdm_->RemoveSession(promise_id, session_id.data(), session_id.size());
}

CdmContext* CdmAdapter::GetCdmContext() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  return this;
}

std::unique_ptr<CallbackRegistration> CdmAdapter::RegisterEventCB(
    EventCB event_cb) {
  return event_callbacks_.Register(std::move(event_cb));
}

Decryptor* CdmAdapter::GetDecryptor() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  return this;
}

std::optional<base::UnguessableToken> CdmAdapter::GetCdmId() const {
  DCHECK(task_runner_->BelongsToCurrentThread());
  return std::nullopt;
}

void CdmAdapter::Decrypt(StreamType stream_type,
                         scoped_refptr<DecoderBuffer> encrypted,
                         DecryptCB decrypt_cb) {
  DVLOG(3) << __func__ << ": "
           << encrypted->AsHumanReadableString(/*verbose=*/true);
  DCHECK(task_runner_->BelongsToCurrentThread());

  cdm::InputBuffer_2 input_buffer = {};
  std::vector<cdm::SubsampleEntry> subsamples;
  std::unique_ptr<DecryptedBlockImpl> decrypted_block(new DecryptedBlockImpl());

  TRACE_EVENT_BEGIN1("media", "CdmAdapter::Decrypt", "stream_type",
                     stream_type);
  ToCdmInputBuffer(*encrypted, &subsamples, &input_buffer);
  cdm::Status status = cdm_->Decrypt(input_buffer, decrypted_block.get());
  TRACE_EVENT_END2("media", "CdmAdapter::Decrypt", "key ID",
                   GetHexKeyId(input_buffer), "status",
                   CdmStatusToString(status));

  if (status != cdm::kSuccess) {
    DVLOG(1) << __func__ << ": status = " << status;
    std::move(decrypt_cb).Run(ToMediaDecryptorStatus(status), nullptr);
    return;
  }

  scoped_refptr<DecoderBuffer> decrypted_buffer(
      DecoderBuffer::CopyFrom(decrypted_block->DecryptedBuffer()->Data(),
                              decrypted_block->DecryptedBuffer()->Size()));
  decrypted_buffer->set_timestamp(
      base::Microseconds(decrypted_block->Timestamp()));
  std::move(decrypt_cb).Run(Decryptor::kSuccess, std::move(decrypted_buffer));
}

void CdmAdapter::CancelDecrypt(StreamType stream_type) {
  // As the Decrypt methods are synchronous, nothing can be done here.
  DCHECK(task_runner_->BelongsToCurrentThread());
}

void CdmAdapter::InitializeAudioDecoder(const AudioDecoderConfig& config,
                                        DecoderInitCB init_cb) {
  DVLOG(2) << __func__ << ": " << config.AsHumanReadableString();
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(!audio_init_cb_);
  TRACE_EVENT0("media", "CdmAdapter::InitializeAudioDecode");

  auto cdm_config = ToCdmAudioDecoderConfig(config);
  if (cdm_config.codec == cdm::kUnknownAudioCodec) {
    DVLOG(1) << __func__
             << ": Unsupported config: " << config.AsHumanReadableString();
    std::move(init_cb).Run(false);
    return;
  }

  cdm::Status status = cdm_->InitializeAudioDecoder(cdm_config);
  if (status != cdm::kSuccess && status != cdm::kDeferredInitialization) {
    DCHECK(status == cdm::kInitializationError);
    DVLOG(1) << __func__ << ": status = " << status;
    std::move(init_cb).Run(false);
    return;
  }

  audio_samples_per_second_ = config.samples_per_second();
  audio_channel_layout_ = config.channel_layout();

  if (status == cdm::kDeferredInitialization) {
    DVLOG(1) << "Deferred initialization in " << __func__;
    audio_init_cb_ = std::move(init_cb);
    return;
  }

  std::move(init_cb).Run(true);
}

void CdmAdapter::InitializeVideoDecoder(const VideoDecoderConfig& config,
                                        DecoderInitCB init_cb) {
  DVLOG(2) << __func__ << ": " << config.AsHumanReadableString();
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(!video_init_cb_);
  TRACE_EVENT0("media", "CdmAdapter::InitializeVideoDecoder");

  // Alpha decoding is not supported by the CDM.
  if (config.alpha_mode() != VideoDecoderConfig::AlphaMode::kIsOpaque) {
    DVLOG(1) << __func__
             << ": Unsupported config: " << config.AsHumanReadableString();
    std::move(init_cb).Run(false);
    return;
  }

  // cdm::kUnknownVideoCodecProfile and cdm::kUnknownVideoFormat are not checked
  // because it's possible the container has wrong information or the demuxer
  // doesn't parse them correctly.
  auto cdm_config = ToCdmVideoDecoderConfig(config);
  if (cdm_config.codec == cdm::kUnknownVideoCodec) {
    DVLOG(1) << __func__
             << ": Unsupported config: " << config.AsHumanReadableString();
    std::move(init_cb).Run(false);
    return;
  }

  cdm::Status status = cdm_->InitializeVideoDecoder(cdm_config);
  if (status != cdm::kSuccess && status != cdm::kDeferredInitialization) {
    DCHECK(status == cdm::kInitializationError);
    DVLOG(1) << __func__ << ": status = " << status;
    std::move(init_cb).Run(false);
    return;
  }

  aspect_ratio_ = config.aspect_ratio();
  is_video_encrypted_ = config.is_encrypted();

  if (status == cdm::kDeferredInitialization) {
    DVLOG(1) << "Deferred initialization in " << __func__;
    video_init_cb_ = std::move(init_cb);
    return;
  }

  std::move(init_cb).Run(true);
}

void CdmAdapter::DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
                                       AudioDecodeCB audio_decode_cb) {
  DVLOG(3) << __func__ << ": "
           << encrypted->AsHumanReadableString(/*verbose=*/true);
  DCHECK(task_runner_->BelongsToCurrentThread());

  cdm::InputBuffer_2 input_buffer = {};
  std::vector<cdm::SubsampleEntry> subsamples;
  std::unique_ptr<AudioFramesImpl> audio_frames(new AudioFramesImpl());

  TRACE_EVENT_BEGIN0("media", "CdmAdapter::DecryptAndDecodeAudio");
  ToCdmInputBuffer(*encrypted, &subsamples, &input_buffer);
  cdm::Status status =
      cdm_->DecryptAndDecodeSamples(input_buffer, audio_frames.get());
  TRACE_EVENT_END2("media", "CdmAdapter::DecryptAndDecodeAudio", "key ID",
                   GetHexKeyId(input_buffer), "status",
                   CdmStatusToString(status));

  const Decryptor::AudioFrames empty_frames;
  if (status != cdm::kSuccess) {
    DVLOG(1) << __func__ << ": status = " << status;
    std::move(audio_decode_cb)
        .Run(ToMediaDecryptorStatus(status), empty_frames);
    return;
  }

  Decryptor::AudioFrames audio_frame_list;
  DCHECK(audio_frames->FrameBuffer());
  if (!AudioFramesDataToAudioFrames(std::move(audio_frames),
                                    &audio_frame_list)) {
    DVLOG(1) << __func__ << " unable to convert Audio Frames";
    std::move(audio_decode_cb).Run(Decryptor::kError, empty_frames);
    return;
  }

  std::move(audio_decode_cb).Run(Decryptor::kSuccess, audio_frame_list);
}

void CdmAdapter::DecryptAndDecodeVideo(scoped_refptr<DecoderBuffer> encrypted,
                                       VideoDecodeCB video_decode_cb) {
  DVLOG(3) << __func__ << ": "
           << encrypted->AsHumanReadableString(/*verbose=*/true);
  DCHECK(task_runner_->BelongsToCurrentThread());

  cdm::InputBuffer_2 input_buffer = {};
  std::vector<cdm::SubsampleEntry> subsamples;
  std::unique_ptr<VideoFrameImpl> video_frame = helper_->CreateCdmVideoFrame();

  TRACE_EVENT_BEGIN1(
      "media", "CdmAdapter::DecryptAndDecodeVideo", "buffer type",
      encrypted->end_of_stream()
          ? "end of stream"
          : (encrypted->is_key_frame() ? "key frame" : "non-key frame"));
  ToCdmInputBuffer(*encrypted, &subsamples, &input_buffer);
  cdm::Status status =
      cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get());
  TRACE_EVENT_END2("media", "CdmAdapter::DecryptAndDecodeVideo", "key ID",
                   GetHexKeyId(input_buffer), "status",
                   CdmStatusToString(status));

  if (status != cdm::kSuccess) {
    DVLOG(1) << __func__ << ": status = " << status;
    std::move(video_decode_cb).Run(ToMediaDecryptorStatus(status), nullptr);
    return;
  }

  gfx::Rect visible_rect(video_frame->Size().width, video_frame->Size().height);
  scoped_refptr<VideoFrame> decoded_frame = video_frame->TransformToVideoFrame(
      aspect_ratio_.GetNaturalSize(visible_rect));
  if (!decoded_frame) {
    DLOG(ERROR) << __func__ << ": TransformToVideoFrame failed.";
    std::move(video_decode_cb).Run(Decryptor::kError, nullptr);
    return;
  }

  decoded_frame->metadata().protected_video = is_video_encrypted_;

  std::move(video_decode_cb).Run(Decryptor::kSuccess, decoded_frame);
}

void CdmAdapter::ResetDecoder(StreamType stream_type) {
  DVLOG(2) << __func__ << ": stream_type = " << stream_type;
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT1("media", "CdmAdapter::ResetDecoder", "stream_type", stream_type);

  cdm_->ResetDecoder(ToCdmStreamType(stream_type));
}

void CdmAdapter::DeinitializeDecoder(StreamType stream_type) {
  DVLOG(2) << __func__ << ": stream_type = " << stream_type;
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT1("media", "CdmAdapter::DeinitializeDecoder", "stream_type",
               stream_type);

  cdm_->DeinitializeDecoder(ToCdmStreamType(stream_type));

  // Reset the saved values from initializing the decoder.
  switch (stream_type) {
    case Decryptor::kAudio:
      audio_samples_per_second_ = 0;
      audio_channel_layout_ = CHANNEL_LAYOUT_NONE;
      break;
    case Decryptor::kVideo:
      aspect_ratio_ = VideoAspectRatio();
      break;
  }
}

cdm::Buffer* CdmAdapter::Allocate(uint32_t capacity) {
  DVLOG(3) << __func__ << ": capacity = " << capacity;
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT1("media", "CdmAdapter::Allocate", "capacity", capacity);

  return helper_->CreateCdmBuffer(capacity);
}

void CdmAdapter::SetTimer(int64_t delay_ms, void* context) {
  DCHECK(task_runner_->BelongsToCurrentThread());

  auto delay = base::Milliseconds(delay_ms);
  DVLOG(3) << __func__ << ": delay = " << delay << ", context = " << context;
  TRACE_EVENT2("media", "CdmAdapter::SetTimer", "delay_ms", delay_ms, "context",
               context);

  task_runner_->PostDelayedTask(
      FROM_HERE,
      base::BindOnce(&CdmAdapter::TimerExpired, weak_factory_.GetWeakPtr(),
                     context),
      delay);
}

void CdmAdapter::TimerExpired(void* context) {
  DVLOG(3) << __func__ << ": context = " << context;
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT1("media", "CdmAdapter::TimerExpired", "context", context);

  cdm_->TimerExpired(context);
}

cdm::Time CdmAdapter::GetCurrentWallTime() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  return base::Time::Now().InSecondsFSinceUnixEpoch();
}

void CdmAdapter::OnInitialized(bool success) {
  DVLOG(3) << __func__ << ": success = " << success;
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK_NE(init_promise_id_, CdmPromiseAdapter::kInvalidPromiseId);

  if (!success) {
    cdm_promise_adapter_.RejectPromise(
        init_promise_id_, CdmPromise::Exception::INVALID_STATE_ERROR, 0,
        "Unable to create CDM.");
  } else {
    cdm_promise_adapter_.ResolvePromise(init_promise_id_);
  }

  init_promise_id_ = CdmPromiseAdapter::kInvalidPromiseId;
}

void CdmAdapter::OnResolveKeyStatusPromise(uint32_t promise_id,
                                           cdm::KeyStatus key_status) {
  DVLOG(2) << __func__ << ": promise_id = " << promise_id
           << ", key_status = " << key_status;
  DCHECK(task_runner_->BelongsToCurrentThread());
  cdm_promise_adapter_.ResolvePromise(promise_id, ToMediaKeyStatus(key_status));
}

void CdmAdapter::OnResolvePromise(uint32_t promise_id) {
  DVLOG(2) << __func__ << ": promise_id = " << promise_id;
  DCHECK(task_runner_->BelongsToCurrentThread());
  cdm_promise_adapter_.ResolvePromise(promise_id);
}

void CdmAdapter::OnResolveNewSessionPromise(uint32_t promise_id,
                                            const char* session_id,
                                            uint32_t session_id_size) {
  DVLOG(2) << __func__ << ": promise_id = " << promise_id;
  DCHECK(task_runner_->BelongsToCurrentThread());
  cdm_promise_adapter_.ResolvePromise(promise_id,
                                      std::string(session_id, session_id_size));
}

void CdmAdapter::OnRejectPromise(uint32_t promise_id,
                                 cdm::Exception exception,
                                 uint32_t system_code,
                                 const char* error_message,
                                 uint32_t error_message_size) {
  std::string error_message_str(error_message, error_message_size);
  DVLOG(2) << __func__ << ": promise_id = " << promise_id
           << ", exception = " << exception << ", system_code = " << system_code
           << ", error_message = " << error_message_str;

  // This is the central place for library CDM promise rejection. Cannot report
  // this in more generic classes like CdmPromise or CdmPromiseAdapter because
  // they may be used multiple times in one promise chain that involves IPC.
  ReportSystemCodeUMA(cdm_config_.key_system, system_code);

  // UMA to help track file related errors. See http://crbug.com/410630
  if (system_code == 0x27) {
    UMA_HISTOGRAM_CUSTOM_COUNTS("Media.EME.CdmFileIO.FileSizeKBOnError",
                                last_read_file_size_kb_, kSizeKBMin, kSizeKBMax,
                                kSizeKBBuckets);
  }

  DCHECK(task_runner_->BelongsToCurrentThread());
  cdm_promise_adapter_.RejectPromise(promise_id,
                                     ToMediaCdmPromiseException(exception),
                                     system_code, error_message_str);
}

void CdmAdapter::OnSessionMessage(const char* session_id,
                                  uint32_t session_id_size,
                                  cdm::MessageType message_type,
                                  const char* message,
                                  uint32_t message_size) {
  std::string session_id_str(session_id, session_id_size);
  DVLOG(2) << __func__ << ": session_id = " << session_id_str;
  DCHECK(task_runner_->BelongsToCurrentThread());

  TRACE_EVENT2("media", "CdmAdapter::OnSessionMessage", "session_id",
               session_id_str, "message_type", message_type);

  const uint8_t* message_ptr = reinterpret_cast<const uint8_t*>(message);
  session_message_cb_.Run(
      session_id_str, ToMediaMessageType(message_type),
      std::vector<uint8_t>(message_ptr, message_ptr + message_size));
}

void CdmAdapter::OnSessionKeysChange(const char* session_id,
                                     uint32_t session_id_size,
                                     bool has_additional_usable_key,
                                     const cdm::KeyInformation* keys_info,
                                     uint32_t keys_info_count) {
  std::string session_id_str(session_id, session_id_size);
  DVLOG(2) << __func__ << ": session_id = " << session_id_str;
  DCHECK(task_runner_->BelongsToCurrentThread());

  TRACE_EVENT2("media", "CdmAdapter::OnSessionKeysChange", "session_id",
               session_id_str, "has_additional_usable_key",
               has_additional_usable_key);

  CdmKeysInfo keys;
  keys.reserve(keys_info_count);
  for (uint32_t i = 0; i < keys_info_count; ++i) {
    const auto& info = keys_info[i];
    keys.push_back(std::make_unique<CdmKeyInformation>(
        info.key_id, info.key_id_size, ToMediaKeyStatus(info.status),
        info.system_code));
  }

  if (has_additional_usable_key)
    event_callbacks_.Notify(Event::kHasAdditionalUsableKey);

  session_keys_change_cb_.Run(session_id_str, has_additional_usable_key,
                              std::move(keys));
}

void CdmAdapter::OnExpirationChange(const char* session_id,
                                    uint32_t session_id_size,
                                    cdm::Time new_expiry_time) {
  std::string session_id_str(session_id, session_id_size);
  DVLOG(2) << __func__ << ": session_id = " << session_id_str
           << ", new_expiry_time = " << new_expiry_time;
  DCHECK(task_runner_->BelongsToCurrentThread());

  base::Time expiration =
      base::Time::FromSecondsSinceUnixEpoch(new_expiry_time);
  TRACE_EVENT2("media", "CdmAdapter::OnExpirationChange", "session_id",
               session_id_str, "new_expiry_time", expiration);
  session_expiration_update_cb_.Run(session_id_str, expiration);
}

void CdmAdapter::OnSessionClosed(const char* session_id,
                                 uint32_t session_id_size) {
  DCHECK(task_runner_->BelongsToCurrentThread());

  std::string session_id_str(session_id, session_id_size);
  TRACE_EVENT1("media", "CdmAdapter::OnSessionClosed", "session_id",
               session_id_str);
  // Library CDMs typically only close sessions as a result of `CloseSession()`.
  session_closed_cb_.Run(session_id_str, CdmSessionClosedReason::kClose);
}

void CdmAdapter::SendPlatformChallenge(const char* service_id,
                                       uint32_t service_id_size,
                                       const char* challenge,
                                       uint32_t challenge_size) {
  DCHECK(task_runner_->BelongsToCurrentThread());

  if (!cdm_config_.allow_distinctive_identifier) {
    task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&CdmAdapter::OnChallengePlatformDone,
                       weak_factory_.GetWeakPtr(), false, "", "", ""));
    return;
  }

  helper_->ChallengePlatform(
      std::string(service_id, service_id_size),
      std::string(challenge, challenge_size),
      base::BindOnce(&CdmAdapter::OnChallengePlatformDone,
                     weak_factory_.GetWeakPtr()));
}

void CdmAdapter::OnChallengePlatformDone(
    bool success,
    const std::string& signed_data,
    const std::string& signed_data_signature,
    const std::string& platform_key_certificate) {
  DVLOG(2) << __func__ << ": success = " << success;
  TRACE_EVENT1("media", "CdmAdapter::OnChallengePlatformDone", "success",
               success);

  cdm::PlatformChallengeResponse platform_challenge_response = {};
  if (success) {
    platform_challenge_response.signed_data =
        reinterpret_cast<const uint8_t*>(signed_data.data());
    platform_challenge_response.signed_data_length = signed_data.length();
    platform_challenge_response.signed_data_signature =
        reinterpret_cast<const uint8_t*>(signed_data_signature.data());
    platform_challenge_response.signed_data_signature_length =
        signed_data_signature.length();
    platform_challenge_response.platform_key_certificate =
        reinterpret_cast<const uint8_t*>(platform_key_certificate.data());
    platform_challenge_response.platform_key_certificate_length =
        platform_key_certificate.length();
  }

  cdm_->OnPlatformChallengeResponse(platform_challenge_response);
}

void CdmAdapter::EnableOutputProtection(uint32_t desired_protection_mask) {
  DVLOG(1) << __func__;
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT1("media", "CdmAdapter::EnableOutputProtection",
               "desired_protection_mask", GetHexMask(desired_protection_mask));

  helper_->EnableProtection(
      desired_protection_mask,
      base::BindOnce(&CdmAdapter::OnEnableOutputProtectionDone,
                     weak_factory_.GetWeakPtr()));
}

void CdmAdapter::OnEnableOutputProtectionDone(bool success) {
  // CDM needs to call QueryOutputProtectionStatus() to see if it took effect
  // or not.
  DVLOG(1) << __func__ << ": success = " << success;
  TRACE_EVENT1("media", "CdmAdapter::OnEnableOutputProtectionDone", "success",
               success);
}

void CdmAdapter::QueryOutputProtectionStatus() {
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT0("media", "CdmAdapter::QueryOutputProtectionStatus");

  ReportOutputProtectionQuery();
  helper_->QueryStatus(
      base::BindOnce(&CdmAdapter::OnQueryOutputProtectionStatusDone,
                     weak_factory_.GetWeakPtr()));
}

void CdmAdapter::OnQueryOutputProtectionStatusDone(bool success,
                                                   uint32_t link_mask,
                                                   uint32_t protection_mask) {
  DVLOG(2) << __func__ << ": success = " << success;
  // Combining |link_mask| and |protection_mask| since there's no TRACE_EVENT3.
  TRACE_EVENT2("media", "CdmAdapter::OnQueryOutputProtectionStatusDone",
               "success", success, "link_mask, protection_mask",
               GetHexMask(link_mask) + ", " + GetHexMask(protection_mask));

  // The bit mask definition must be consistent between media::OutputProtection
  // and cdm::ContentDecryptionModule* interfaces. This is statically asserted
  // by ASSERT_ENUM_EQs above.

  // Return a query status of failure on error.
  cdm::QueryResult query_result;
  if (success) {
    query_result = cdm::kQuerySucceeded;
    ReportOutputProtectionQueryResult(link_mask, protection_mask);
  } else {
    DVLOG(1) << __func__ << ": query output protection status failed";
    query_result = cdm::kQueryFailed;
  }

  cdm_->OnQueryOutputProtectionStatus(query_result, link_mask, protection_mask);
}

void CdmAdapter::ReportOutputProtectionQuery() {
  if (uma_for_output_protection_query_reported_)
    return;

  ReportOutputProtectionUMA(OutputProtectionStatus::kQueried);
  uma_for_output_protection_query_reported_ = true;
}

void CdmAdapter::ReportOutputProtectionQueryResult(uint32_t link_mask,
                                                   uint32_t protection_mask) {
  DCHECK(uma_for_output_protection_query_reported_);

  if (uma_for_output_protection_positive_result_reported_)
    return;

  // Report UMAs for output protection query result.

  uint32_t external_links = (link_mask & ~cdm::kLinkTypeInternal);

  if (!external_links) {
    ReportOutputProtectionUMA(OutputProtectionStatus::kNoExternalLink);
    uma_for_output_protection_positive_result_reported_ = true;
    return;
  }

  const uint32_t kProtectableLinks =
      cdm::kLinkTypeHDMI | cdm::kLinkTypeDVI | cdm::kLinkTypeDisplayPort;
  bool is_unprotectable_link_connected =
      (external_links & ~kProtectableLinks) != 0;
  bool is_hdcp_enabled_on_all_protectable_links =
      (protection_mask & cdm::kProtectionHDCP) != 0;

  if (!is_unprotectable_link_connected &&
      is_hdcp_enabled_on_all_protectable_links) {
    ReportOutputProtectionUMA(
        OutputProtectionStatus::kAllExternalLinksProtected);
    uma_for_output_protection_positive_result_reported_ = true;
    return;
  }

  // Do not report a negative result because it could be a false negative.
  // Instead, we will calculate number of negatives using the total number of
  // queries and positive results.
}

void CdmAdapter::OnDeferredInitializationDone(cdm::StreamType stream_type,
                                              cdm::Status decoder_status) {
  DVLOG(1) << __func__ << ": stream_type = " << stream_type
           << ", decoder_status = " << decoder_status;
  DCHECK(task_runner_->BelongsToCurrentThread());

  switch (stream_type) {
    case cdm::kStreamTypeAudio:
      std::move(audio_init_cb_).Run(decoder_status == cdm::kSuccess);
      return;
    case cdm::kStreamTypeVideo:
      std::move(video_init_cb_).Run(decoder_status == cdm::kSuccess);
      return;
  }

  NOTREACHED_NORETURN() << "Unexpected cdm::StreamType " << stream_type;
}

cdm::FileIO* CdmAdapter::CreateFileIO(cdm::FileIOClient* client) {
  DVLOG(3) << __func__;
  DCHECK(task_runner_->BelongsToCurrentThread());

  if (!cdm_config_.allow_persistent_state) {
    DVLOG(1) << __func__ << ": Persistent state not allowed.";
    return nullptr;
  }

  return helper_->CreateCdmFileIO(client);
}

void CdmAdapter::RequestStorageId(uint32_t version) {
  DVLOG(2) << __func__ << ": version = " << version;
  DCHECK(task_runner_->BelongsToCurrentThread());

  if (!cdm_config_.allow_persistent_state ||
      !(version == kCurrentStorageIdVersion ||
        version == kRequestLatestStorageIdVersion)) {
    DVLOG(1) << __func__ << ": Persistent state not allowed ("
             << cdm_config_.allow_persistent_state
             << ") or invalid storage ID version (" << version << ").";
    task_runner_->PostTask(FROM_HERE,
                           base::BindOnce(&CdmAdapter::OnStorageIdObtained,
                                          weak_factory_.GetWeakPtr(), version,
                                          std::vector<uint8_t>()));
    return;
  }

  helper_->GetStorageId(version,
                        base::BindOnce(&CdmAdapter::OnStorageIdObtained,
                                       weak_factory_.GetWeakPtr()));
}

void CdmAdapter::OnStorageIdObtained(uint32_t version,
                                     const std::vector<uint8_t>& storage_id) {
  DVLOG(2) << __func__ << ": version = " << version;
  DCHECK(task_runner_->BelongsToCurrentThread());
  TRACE_EVENT1("media", "CdmAdapter::OnStorageIdObtained", "version", version);

  cdm_->OnStorageId(version, storage_id.data(), storage_id.size());
}

bool CdmAdapter::AudioFramesDataToAudioFrames(
    std::unique_ptr<AudioFramesImpl> audio_frames,
    Decryptor::AudioFrames* result_frames) {
  const uint8_t* data = audio_frames->FrameBuffer()->Data();
  const size_t data_size = audio_frames->FrameBuffer()->Size();
  size_t bytes_left = data_size;
  const SampleFormat sample_format =
      ToMediaSampleFormat(audio_frames->Format());
  const int audio_channel_count =
      ChannelLayoutToChannelCount(audio_channel_layout_);
  const int audio_bytes_per_frame =
      SampleFormatToBytesPerChannel(sample_format) * audio_channel_count;
  if (audio_bytes_per_frame <= 0)
    return false;

  // Allocate space for the channel pointers given to AudioBuffer.
  std::vector<const uint8_t*> channel_ptrs(audio_channel_count, nullptr);
  do {
    // AudioFrames can contain multiple audio output buffers, which are
    // serialized into this format:
    // |<------------------- serialized audio buffer ------------------->|
    // | int64_t timestamp | int64_t length | length bytes of audio data |
    int64_t timestamp = 0;
    int64_t frame_size = -1;
    const size_t kHeaderSize = sizeof(timestamp) + sizeof(frame_size);
    if (bytes_left < kHeaderSize)
      return false;

    memcpy(&timestamp, data, sizeof(timestamp));
    memcpy(&frame_size, data + sizeof(timestamp), sizeof(frame_size));
    data += kHeaderSize;
    bytes_left -= kHeaderSize;

    // We should *not* have empty frames in the list.
    if (frame_size <= 0 ||
        bytes_left < base::checked_cast<size_t>(frame_size)) {
      return false;
    }

    // Setup channel pointers.  AudioBuffer::CopyFrom() will only use the first
    // one in the case of interleaved data.
    const int size_per_channel = frame_size / audio_channel_count;
    for (int i = 0; i < audio_channel_count; ++i)
      channel_ptrs[i] = data + i * size_per_channel;

    const int frame_count = frame_size / audio_bytes_per_frame;
    scoped_refptr<media::AudioBuffer> frame = media::AudioBuffer::CopyFrom(
        sample_format, audio_channel_layout_, audio_channel_count,
        audio_samples_per_second_, frame_count, &channel_ptrs[0],
        base::Microseconds(timestamp), pool_);
    result_frames->push_back(frame);

    data += frame_size;
    bytes_left -= frame_size;
  } while (bytes_left > 0);

  return true;
}

void CdmAdapter::OnFileRead(int file_size_bytes) {
  DCHECK_GE(file_size_bytes, 0);
  last_read_file_size_kb_ = file_size_bytes / 1024;

  if (file_size_uma_reported_)
    return;

  UMA_HISTOGRAM_CUSTOM_COUNTS("Media.EME.CdmFileIO.FileSizeKBOnFirstRead",
                              last_read_file_size_kb_, kSizeKBMin, kSizeKBMax,
                              kSizeKBBuckets);
  file_size_uma_reported_ = true;
}

}  // namespace media
