// Copyright 2018 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 "media/renderers/decrypting_renderer.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "media/base/demuxer_stream.h"
#include "media/base/media_log.h"
#include "media/base/media_resource.h"
#include "media/base/renderer_client.h"
#include "media/filters/decrypting_demuxer_stream.h"
#include "media/filters/decrypting_media_resource.h"

namespace media {

DecryptingRenderer::DecryptingRenderer(
    std::unique_ptr<Renderer> renderer,
    MediaLog* media_log,
    const scoped_refptr<base::SingleThreadTaskRunner> media_task_runner)
    : renderer_(std::move(renderer)),
      media_log_(media_log),
      media_task_runner_(media_task_runner),
      client_(nullptr),
      media_resource_(nullptr),
      decrypting_media_resource_(nullptr) {
  DCHECK(renderer_);
}

DecryptingRenderer::~DecryptingRenderer() {}

// The behavior of Initialize():
//
// Streams    CdmContext    Action
// ---------------------------------------------------------------------
// Clear      nullptr       InitializeRenderer()
// Clear      AesDecryptor  CreateAndInitializeDecryptingMediaResource()
// Clear      Other         InitializeRenderer()
// Encrypted  nullptr       Wait
// Encrypted  AesDecryptor  CreateAndInitializeDecryptingMediaResource()
// Encrypted  Other         InitializeRenderer()
void DecryptingRenderer::Initialize(MediaResource* media_resource,
                                    RendererClient* client,
                                    PipelineStatusCallback init_cb) {
  DCHECK(media_task_runner_->BelongsToCurrentThread());
  DCHECK(media_resource);
  DCHECK(client);

  // Using |this| with a MediaResource::Type::URL will result in a crash.
  DCHECK_EQ(media_resource->GetType(), MediaResource::Type::STREAM);

  media_resource_ = media_resource;
  client_ = client;
  init_cb_ = std::move(init_cb);

  bool has_encrypted_stream = HasEncryptedStream();

  // If we do not have a valid |cdm_context_| and there are encrypted streams we
  // need to wait.
  if (!cdm_context_ && has_encrypted_stream) {
    waiting_for_cdm_ = true;
    return;
  }

  if (cdm_context_ && cdm_context_->GetDecryptor() &&
      cdm_context_->GetDecryptor()->CanAlwaysDecrypt()) {
    CreateAndInitializeDecryptingMediaResource();
    return;
  }

  InitializeRenderer(true);
}

void DecryptingRenderer::SetCdm(CdmContext* cdm_context,
                                CdmAttachedCB cdm_attached_cb) {
  DCHECK(media_task_runner_->BelongsToCurrentThread());

  if (cdm_context_) {
    DVLOG(1) << "Switching CDM not supported.";
    std::move(cdm_attached_cb).Run(false);
    return;
  }

  cdm_context_ = cdm_context;

  // If we are using an AesDecryptor all decryption will be handled by the
  // DecryptingMediaResource instead of the renderer implementation.
  if (cdm_context_->GetDecryptor() &&
      cdm_context_->GetDecryptor()->CanAlwaysDecrypt()) {
    // If Initialize() was invoked prior to this function then
    // |waiting_for_cdm_| will be true (if we reached this branch). In this
    // scenario we want to initialize the DecryptingMediaResource here.
    if (waiting_for_cdm_)
      CreateAndInitializeDecryptingMediaResource();
    std::move(cdm_attached_cb).Run(true);
    return;
  }

  renderer_->SetCdm(cdm_context_, std::move(cdm_attached_cb));

  // We only want to initialize the renderer if we were waiting for the
  // CdmContext, otherwise it will already have been initialized.
  if (waiting_for_cdm_)
    InitializeRenderer(true);
}

void DecryptingRenderer::Flush(base::OnceClosure flush_cb) {
  renderer_->Flush(std::move(flush_cb));
}

void DecryptingRenderer::StartPlayingFrom(base::TimeDelta time) {
  renderer_->StartPlayingFrom(time);
}

void DecryptingRenderer::SetPlaybackRate(double playback_rate) {
  renderer_->SetPlaybackRate(playback_rate);
}

void DecryptingRenderer::SetVolume(float volume) {
  renderer_->SetVolume(volume);
}

base::TimeDelta DecryptingRenderer::GetMediaTime() {
  return renderer_->GetMediaTime();
}

void DecryptingRenderer::OnSelectedVideoTracksChanged(
    const std::vector<DemuxerStream*>& enabled_tracks,
    base::OnceClosure change_completed_cb) {
  renderer_->OnSelectedVideoTracksChanged(enabled_tracks,
                                          std::move(change_completed_cb));
}

void DecryptingRenderer::OnEnabledAudioTracksChanged(
    const std::vector<DemuxerStream*>& enabled_tracks,
    base::OnceClosure change_completed_cb) {
  renderer_->OnEnabledAudioTracksChanged(enabled_tracks,
                                         std::move(change_completed_cb));
}

void DecryptingRenderer::CreateAndInitializeDecryptingMediaResource() {
  DCHECK(media_task_runner_->BelongsToCurrentThread());
  DCHECK(init_cb_);

  decrypting_media_resource_ = std::make_unique<DecryptingMediaResource>(
      media_resource_, cdm_context_, media_log_, media_task_runner_);
  decrypting_media_resource_->Initialize(
      base::BindOnce(&DecryptingRenderer::InitializeRenderer,
                     weak_factory_.GetWeakPtr()),
      base::BindRepeating(&DecryptingRenderer::OnWaiting,
                          weak_factory_.GetWeakPtr()));
}

void DecryptingRenderer::InitializeRenderer(bool success) {
  DCHECK(media_task_runner_->BelongsToCurrentThread());

  if (!success) {
    std::move(init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
    return;
  }

  // |decrypting_media_resource_| when |cdm_context_| is null and there are no
  // encrypted streams.
  MediaResource* const maybe_decrypting_media_resource =
      decrypting_media_resource_ ? decrypting_media_resource_.get()
                                 : media_resource_;
  renderer_->Initialize(maybe_decrypting_media_resource, client_,
                        std::move(init_cb_));
}

bool DecryptingRenderer::HasEncryptedStream() {
  DCHECK(media_task_runner_->BelongsToCurrentThread());

  for (auto* stream : media_resource_->GetAllStreams()) {
    if ((stream->type() == DemuxerStream::AUDIO &&
         stream->audio_decoder_config().is_encrypted()) ||
        (stream->type() == DemuxerStream::VIDEO &&
         stream->video_decoder_config().is_encrypted())) {
      return true;
    }
  }

  return false;
}

bool DecryptingRenderer::HasDecryptingMediaResourceForTesting() const {
  return decrypting_media_resource_ != nullptr;
}

void DecryptingRenderer::OnWaiting(WaitingReason reason) {
  DCHECK(media_task_runner_->BelongsToCurrentThread());
  client_->OnWaiting(reason);
}

}  // namespace media
