// Copyright 2014 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/mojo/clients/mojo_cdm.h"

#include <stddef.h>

#include <utility>

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/single_thread_task_runner.h"
#include "base/types/optional_util.h"
#include "build/build_config.h"
#include "media/base/callback_timeout_helpers.h"
#include "media/base/cdm_context.h"
#include "media/base/cdm_key_information.h"
#include "media/base/cdm_promise.h"
#include "media/base/key_systems.h"
#include "media/media_buildflags.h"
#include "media/mojo/clients/mojo_decryptor.h"
#include "media/mojo/common/media_type_converters.h"
#include "media/mojo/mojom/decryptor.mojom.h"
#include "services/service_manager/public/cpp/connect.h"
#include "services/service_manager/public/mojom/interface_provider.mojom.h"

namespace media {

namespace {

void RecordConnectionError(bool connection_error_happened) {
  UMA_HISTOGRAM_BOOLEAN("Media.EME.MojoCdm.ConnectionError",
                        connection_error_happened);
}

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class CallbackTimeoutStatus {
  kCreate = 0,
  kTimeout = 1,
  kDestructedBeforeTimeout = 2,
  kMaxValue = kDestructedBeforeTimeout,
};

void OnCallbackTimeout(const std::string uma_name, bool called_on_destruction) {
  DVLOG(1) << "Callback Timeout: " << uma_name
           << ", called_on_destruction=" << called_on_destruction;
  base::UmaHistogramEnumeration(
      uma_name, called_on_destruction
                    ? CallbackTimeoutStatus::kDestructedBeforeTimeout
                    : CallbackTimeoutStatus::kTimeout);
}

constexpr auto kMojoCdmTimeout = base::Seconds(20);

}  // namespace

MojoCdm::MojoCdm(mojo::Remote<mojom::ContentDecryptionModule> remote_cdm,
                 media::mojom::CdmContextPtr cdm_context,
                 const CdmConfig& cdm_config,
                 const SessionMessageCB& session_message_cb,
                 const SessionClosedCB& session_closed_cb,
                 const SessionKeysChangeCB& session_keys_change_cb,
                 const SessionExpirationUpdateCB& session_expiration_update_cb)
    : remote_cdm_(std::move(remote_cdm)),
      cdm_id_(cdm_context->cdm_id),
      decryptor_remote_(std::move(cdm_context->decryptor)),
#if BUILDFLAG(IS_WIN)
      requires_media_foundation_renderer_(
          cdm_context->requires_media_foundation_renderer),
#endif  // BUILDFLAG(IS_WIN)
      cdm_config_(cdm_config),
      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) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(cdm_id_);
  DVLOG(2) << __func__ << " cdm_id: "
           << CdmContext::CdmIdToString(base::OptionalToPtr(cdm_id_));
  DCHECK(session_message_cb_);
  DCHECK(session_closed_cb_);
  DCHECK(session_keys_change_cb_);
  DCHECK(session_expiration_update_cb_);

  remote_cdm_->SetClient(client_receiver_.BindNewEndpointAndPassRemote());

  // Report a false event here as a baseline.
  RecordConnectionError(false);

  // Otherwise, set an error handler to catch the connection error.
  remote_cdm_.set_disconnect_with_reason_handler(
      base::BindOnce(&MojoCdm::OnConnectionError, base::Unretained(this)));
}

MojoCdm::~MojoCdm() {
  DVLOG(1) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  base::AutoLock auto_lock(lock_);

  // Release |decryptor_| on the correct thread. If GetDecryptor() is never
  // called but |decryptor_remote_| is not null, it is not bound to any
  // thread and is safe to be released on the current thread.
  if (decryptor_task_runner_ &&
      !decryptor_task_runner_->BelongsToCurrentThread() && decryptor_) {
    decryptor_task_runner_->DeleteSoon(FROM_HERE, decryptor_.release());
  }

  // Reject any outstanding promises and close all the existing sessions.
  cdm_promise_adapter_.Clear(CdmPromiseAdapter::ClearReason::kDestruction);
  cdm_session_tracker_.CloseRemainingSessions(
      session_closed_cb_, CdmSessionClosedReason::kInternalError);
}

// Using base::Unretained(this) below is safe because |this| owns |remote_cdm_|,
// and if |this| is destroyed, |remote_cdm_| will be destroyed as well. Then the
// error handler can't be invoked and callbacks won't be dispatched.

void MojoCdm::OnConnectionError(uint32_t custom_reason,
                                const std::string& description) {
  LOG(ERROR) << "Remote CDM connection error: custom_reason=" << custom_reason
             << ", description=\"" << description << "\"";
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  RecordConnectionError(true);

  remote_cdm_.reset();

  // As communication with the remote CDM is broken, reject any outstanding
  // promises and close all the existing sessions.
  cdm_promise_adapter_.Clear(CdmPromiseAdapter::ClearReason::kConnectionError);
  cdm_session_tracker_.CloseRemainingSessions(
      session_closed_cb_, CdmSessionClosedReason::kInternalError);
}

void MojoCdm::SetServerCertificate(const std::vector<uint8_t>& certificate,
                                   std::unique_ptr<SimpleCdmPromise> promise) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

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

  if (!remote_cdm_) {
    RejectPromiseConnectionLost(promise_id);
    return;
  }

  remote_cdm_->SetServerCertificate(
      certificate, base::BindOnce(&MojoCdm::OnSimpleCdmPromiseResult,
                                  base::Unretained(this), promise_id));
}

void MojoCdm::GetStatusForPolicy(HdcpVersion min_hdcp_version,
                                 std::unique_ptr<KeyStatusCdmPromise> promise) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

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

  if (!remote_cdm_) {
    RejectPromiseConnectionLost(promise_id);
    return;
  }

  remote_cdm_->GetStatusForPolicy(
      min_hdcp_version, base::BindOnce(&MojoCdm::OnKeyStatusCdmPromiseResult,
                                       base::Unretained(this), promise_id));
}

void MojoCdm::CreateSessionAndGenerateRequest(
    CdmSessionType session_type,
    EmeInitDataType init_data_type,
    const std::vector<uint8_t>& init_data,
    std::unique_ptr<NewSessionCdmPromise> promise) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

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

  if (!remote_cdm_) {
    RejectPromiseConnectionLost(promise_id);
    return;
  }

  std::string uma_name =
      "Media.EME." +
      GetKeySystemNameForUMA(cdm_config_.key_system,
                             cdm_config_.use_hw_secure_codecs) +
      ".GenerateRequest.MojoCdmTimeout";
  // Report "kCreate" as a baseline.
  base::UmaHistogramEnumeration(uma_name, CallbackTimeoutStatus::kCreate);

  remote_cdm_->CreateSessionAndGenerateRequest(
      session_type, init_data_type, init_data,
      WrapCallbackWithTimeoutHandler(
          base::BindOnce(&MojoCdm::OnNewSessionCdmPromiseResult,
                         base::Unretained(this), promise_id),
          kMojoCdmTimeout, base::BindOnce(&OnCallbackTimeout, uma_name)));
}

void MojoCdm::LoadSession(CdmSessionType session_type,
                          const std::string& session_id,
                          std::unique_ptr<NewSessionCdmPromise> promise) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

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

  if (!remote_cdm_) {
    RejectPromiseConnectionLost(promise_id);
    return;
  }

  remote_cdm_->LoadSession(
      session_type, session_id,
      base::BindOnce(&MojoCdm::OnNewSessionCdmPromiseResult,
                     base::Unretained(this), promise_id));
}

void MojoCdm::UpdateSession(const std::string& session_id,
                            const std::vector<uint8_t>& response,
                            std::unique_ptr<SimpleCdmPromise> promise) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

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

  if (!remote_cdm_) {
    RejectPromiseConnectionLost(promise_id);
    return;
  }

  remote_cdm_->UpdateSession(
      session_id, response,
      base::BindOnce(&MojoCdm::OnSimpleCdmPromiseResult, base::Unretained(this),
                     promise_id));
}

void MojoCdm::CloseSession(const std::string& session_id,
                           std::unique_ptr<SimpleCdmPromise> promise) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

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

  if (!remote_cdm_) {
    RejectPromiseConnectionLost(promise_id);
    return;
  }

  remote_cdm_->CloseSession(session_id,
                            base::BindOnce(&MojoCdm::OnSimpleCdmPromiseResult,
                                           base::Unretained(this), promise_id));
}

void MojoCdm::RemoveSession(const std::string& session_id,
                            std::unique_ptr<SimpleCdmPromise> promise) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

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

  if (!remote_cdm_) {
    RejectPromiseConnectionLost(promise_id);
    return;
  }

  remote_cdm_->RemoveSession(
      session_id, base::BindOnce(&MojoCdm::OnSimpleCdmPromiseResult,
                                 base::Unretained(this), promise_id));
}

CdmContext* MojoCdm::GetCdmContext() {
  DVLOG(2) << __func__;
  return this;
}

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

Decryptor* MojoCdm::GetDecryptor() {
  base::AutoLock auto_lock(lock_);

  if (!decryptor_task_runner_)
    decryptor_task_runner_ = base::SingleThreadTaskRunner::GetCurrentDefault();
  DCHECK(decryptor_task_runner_->BelongsToCurrentThread());

  if (decryptor_)
    return decryptor_.get();

  // Can be called on a different thread.
  if (decryptor_remote_.is_valid()) {
    DVLOG(1) << __func__ << ": Using Decryptor exposed by the CDM directly";
    decryptor_ = std::make_unique<MojoDecryptor>(std::move(decryptor_remote_));
  }

  return decryptor_.get();
}

absl::optional<base::UnguessableToken> MojoCdm::GetCdmId() const {
  // Can be called on a different thread.
  base::AutoLock auto_lock(lock_);
  DVLOG(2) << __func__ << ": cdm_id="
           << CdmContext::CdmIdToString(base::OptionalToPtr(cdm_id_));
  return cdm_id_;
}

#if BUILDFLAG(IS_WIN)
bool MojoCdm::RequiresMediaFoundationRenderer() {
  base::AutoLock auto_lock(lock_);
  DVLOG(2) << __func__ << ": requires_media_foundation_renderer_="
           << requires_media_foundation_renderer_;
  return requires_media_foundation_renderer_;
}
#endif  // BUILDFLAG(IS_WIN)

void MojoCdm::OnSessionMessage(const std::string& session_id,
                               MessageType message_type,
                               const std::vector<uint8_t>& message) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  session_message_cb_.Run(session_id, message_type, message);
}

void MojoCdm::OnSessionClosed(const std::string& session_id,
                              CdmSessionClosedReason reason) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  cdm_session_tracker_.RemoveSession(session_id);
  session_closed_cb_.Run(session_id, reason);
}

void MojoCdm::OnSessionKeysChange(
    const std::string& session_id,
    bool has_additional_usable_key,
    std::vector<std::unique_ptr<CdmKeyInformation>> keys_info) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

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

  session_keys_change_cb_.Run(session_id, has_additional_usable_key,
                              std::move(keys_info));
}

void MojoCdm::OnSessionExpirationUpdate(const std::string& session_id,
                                        double new_expiry_time_sec) {
  DVLOG(2) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  session_expiration_update_cb_.Run(
      session_id, base::Time::FromDoubleT(new_expiry_time_sec));
}

void MojoCdm::OnSimpleCdmPromiseResult(uint32_t promise_id,
                                       mojom::CdmPromiseResultPtr result) {
  if (result->success)
    cdm_promise_adapter_.ResolvePromise(promise_id);
  else {
    cdm_promise_adapter_.RejectPromise(promise_id, result->exception,
                                       result->system_code,
                                       result->error_message);
  }
}

void MojoCdm::OnKeyStatusCdmPromiseResult(
    uint32_t promise_id,
    mojom::CdmPromiseResultPtr result,
    CdmKeyInformation::KeyStatus key_status) {
  if (result->success) {
    cdm_promise_adapter_.ResolvePromise(promise_id, key_status);
  } else {
    cdm_promise_adapter_.RejectPromise(promise_id, result->exception,
                                       result->system_code,
                                       result->error_message);
  }
}

void MojoCdm::OnNewSessionCdmPromiseResult(uint32_t promise_id,
                                           mojom::CdmPromiseResultPtr result,
                                           const std::string& session_id) {
  if (result->success) {
    cdm_session_tracker_.AddSession(session_id);
    cdm_promise_adapter_.ResolvePromise(promise_id, session_id);
  } else {
    cdm_promise_adapter_.RejectPromise(promise_id, result->exception,
                                       result->system_code,
                                       result->error_message);
  }
}

void MojoCdm::RejectPromiseConnectionLost(uint32_t promise_id) {
  cdm_promise_adapter_.RejectPromise(
      promise_id, CdmPromise::Exception::INVALID_STATE_ERROR,
      CdmPromise::SystemCode::kConnectionError, "CDM connection lost.");
}

}  // namespace media
