// Copyright 2017 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/mojo/services/media_metrics_provider.h"

#include <memory>
#include <utility>

#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "build/chromecast_buildflags.h"
#include "media/base/key_systems.h"
#include "media/learning/mojo/mojo_learning_task_controller_service.h"
#include "media/mojo/services/video_decode_stats_recorder.h"
#include "media/mojo/services/watch_time_recorder.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"

#if !defined(OS_ANDROID)
#include "media/filters/decrypting_video_decoder.h"
#endif  // !defined(OS_ANDROID)

#if defined(OS_FUCHSIA) || (BUILDFLAG(IS_CHROMECAST) && defined(OS_ANDROID))
#include "media/mojo/services/playback_events_recorder.h"
#endif

namespace media {

constexpr char kInvalidInitialize[] = "Initialize() was not called correctly.";

static uint64_t g_player_id = 0;

MediaMetricsProvider::PipelineInfo::PipelineInfo(bool is_incognito)
    : is_incognito(is_incognito) {}

MediaMetricsProvider::PipelineInfo::~PipelineInfo() = default;

MediaMetricsProvider::MediaMetricsProvider(
    BrowsingMode is_incognito,
    FrameStatus is_top_frame,
    ukm::SourceId source_id,
    learning::FeatureValue origin,
    VideoDecodePerfHistory::SaveCallback save_cb,
    GetLearningSessionCallback learning_session_cb,
    RecordAggregateWatchTimeCallback record_playback_cb)
    : player_id_(g_player_id++),
      is_top_frame_(is_top_frame == FrameStatus::kTopFrame),
      source_id_(source_id),
      origin_(origin),
      save_cb_(std::move(save_cb)),
      learning_session_cb_(std::move(learning_session_cb)),
      record_playback_cb_(std::move(record_playback_cb)),
      uma_info_(is_incognito == BrowsingMode::kIncognito) {}

MediaMetricsProvider::~MediaMetricsProvider() {
  // These UKM and UMA metrics do not apply to MediaStreams.
  if (media_stream_type_ != mojom::MediaStreamType::kNone)
    return;

  // UKM may be unavailable in content_shell or other non-chrome/ builds; it
  // may also be unavailable if browser shutdown has started; so this may be a
  // nullptr. If it's unavailable, UKM reporting will be skipped.
  ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
  if (!ukm_recorder || !initialized_)
    return;

  ukm::builders::Media_WebMediaPlayerState builder(source_id_);
  builder.SetPlayerID(player_id_);
  builder.SetIsTopFrame(is_top_frame_);
  builder.SetIsEME(uma_info_.is_eme);
  builder.SetIsMSE(is_mse_);
  builder.SetRendererType(static_cast<int>(renderer_type_));
  builder.SetKeySystem(GetKeySystemIntForUKM(key_system_));
  builder.SetIsHardwareSecure(is_hardware_secure_);
  builder.SetAudioEncryptionType(
      static_cast<int>(uma_info_.audio_pipeline_info.encryption_type));
  builder.SetVideoEncryptionType(
      static_cast<int>(uma_info_.video_pipeline_info.encryption_type));
  builder.SetFinalPipelineStatus(uma_info_.last_pipeline_status);
  if (!is_mse_) {
    builder.SetURLScheme(static_cast<int64_t>(url_scheme_));
    if (container_name_)
      builder.SetContainerName(*container_name_);
  }

  if (time_to_metadata_ != kNoTimestamp)
    builder.SetTimeToMetadata(time_to_metadata_.InMilliseconds());
  if (time_to_first_frame_ != kNoTimestamp)
    builder.SetTimeToFirstFrame(time_to_first_frame_.InMilliseconds());
  if (time_to_play_ready_ != kNoTimestamp)
    builder.SetTimeToPlayReady(time_to_play_ready_.InMilliseconds());

  builder.Record(ukm_recorder);
  ReportPipelineUMA();
}

std::string MediaMetricsProvider::GetUMANameForAVStream(
    const PipelineInfo& player_info) {
  constexpr char kPipelineUmaPrefix[] = "Media.PipelineStatus.AudioVideo.";
  std::string uma_name = kPipelineUmaPrefix;
  if (player_info.video_codec == VideoCodec::kVP8)
    uma_name += "VP8.";
  else if (player_info.video_codec == VideoCodec::kVP9)
    uma_name += "VP9.";
  else if (player_info.video_codec == VideoCodec::kH264)
    uma_name += "H264.";
  else if (player_info.video_codec == VideoCodec::kAV1)
    uma_name += "AV1.";
  else
    return uma_name + "Other";

  // Add Renderer name when not using the default RendererImpl.
  if (renderer_type_ == RendererType::kMediaFoundation) {
    return uma_name + GetRendererName(RendererType::kMediaFoundation);
  } else if (renderer_type_ != RendererType::kDefault) {
    return uma_name + "UnknownRenderer";
  }

  // Using default RendererImpl. Put more detailed info into the UMA name.
#if !defined(OS_ANDROID)
  if (player_info.video_pipeline_info.decoder_type ==
      VideoDecoderType::kDecrypting) {
    return uma_name + "DVD";
  }
#endif

  if (player_info.video_pipeline_info.has_decrypting_demuxer_stream)
    uma_name += "DDS.";

  // Note that HW essentially means 'platform' anyway. MediaCodec has been
  // reported as HW forever, regardless of the underlying platform
  // implementation.
  uma_name += player_info.video_pipeline_info.is_platform_decoder ? "HW" : "SW";

  return uma_name;
}

void MediaMetricsProvider::ReportPipelineUMA() {
  if (uma_info_.has_video && uma_info_.has_audio) {
    base::UmaHistogramExactLinear(GetUMANameForAVStream(uma_info_),
                                  uma_info_.last_pipeline_status,
                                  PIPELINE_STATUS_MAX + 1);
  } else if (uma_info_.has_audio) {
    base::UmaHistogramExactLinear("Media.PipelineStatus.AudioOnly",
                                  uma_info_.last_pipeline_status,
                                  PIPELINE_STATUS_MAX + 1);
  } else if (uma_info_.has_video) {
    base::UmaHistogramExactLinear("Media.PipelineStatus.VideoOnly",
                                  uma_info_.last_pipeline_status,
                                  PIPELINE_STATUS_MAX + 1);
  } else {
    // Note: This metric can be recorded as a result of normal operation with
    // Media Source Extensions. If a site creates a MediaSource object but never
    // creates a source buffer or appends data, PIPELINE_OK will be recorded.
    base::UmaHistogramExactLinear("Media.PipelineStatus.Unsupported",
                                  uma_info_.last_pipeline_status,
                                  PIPELINE_STATUS_MAX + 1);
  }

  // Report whether video decoder fallback happened, but only if a video decoder
  // was reported.
  if (uma_info_.video_pipeline_info.decoder_type !=
      VideoDecoderType::kUnknown) {
    base::UmaHistogramBoolean("Media.VideoDecoderFallback",
                              uma_info_.video_decoder_changed);
  }

  // Report whether this player ever saw a playback event. Used to measure the
  // effectiveness of efforts to reduce loaded-but-never-used players.
  if (uma_info_.has_reached_have_enough)
    base::UmaHistogramBoolean("Media.HasEverPlayed", uma_info_.has_ever_played);

  // Report whether an encrypted playback is in incognito window, excluding
  // never-used players.
  if (uma_info_.is_eme && uma_info_.has_ever_played)
    base::UmaHistogramBoolean("Media.EME.IsIncognito", uma_info_.is_incognito);
}

// static
void MediaMetricsProvider::Create(
    BrowsingMode is_incognito,
    FrameStatus is_top_frame,
    ukm::SourceId source_id,
    learning::FeatureValue origin,
    VideoDecodePerfHistory::SaveCallback save_cb,
    GetLearningSessionCallback learning_session_cb,
    GetRecordAggregateWatchTimeCallback get_record_playback_cb,
    mojo::PendingReceiver<mojom::MediaMetricsProvider> receiver) {
  mojo::MakeSelfOwnedReceiver(
      std::make_unique<MediaMetricsProvider>(
          is_incognito, is_top_frame, source_id, origin, std::move(save_cb),
          std::move(learning_session_cb),
          std::move(get_record_playback_cb).Run()),
      std::move(receiver));
}

void MediaMetricsProvider::SetHasPlayed() {
  uma_info_.has_ever_played = true;
}

void MediaMetricsProvider::SetHasAudio(AudioCodec audio_codec) {
  uma_info_.audio_codec = audio_codec;
  uma_info_.has_audio = true;
}

void MediaMetricsProvider::SetHasVideo(VideoCodec video_codec) {
  uma_info_.video_codec = video_codec;
  uma_info_.has_video = true;
}

void MediaMetricsProvider::SetHaveEnough() {
  uma_info_.has_reached_have_enough = true;
}

void MediaMetricsProvider::SetVideoPipelineInfo(const VideoPipelineInfo& info) {
  auto old_decoder = uma_info_.video_pipeline_info.decoder_type;
  if (old_decoder != VideoDecoderType::kUnknown &&
      old_decoder != info.decoder_type)
    uma_info_.video_decoder_changed = true;
  uma_info_.video_pipeline_info = info;
}

void MediaMetricsProvider::SetAudioPipelineInfo(const AudioPipelineInfo& info) {
  uma_info_.audio_pipeline_info = info;
}

void MediaMetricsProvider::Initialize(
    bool is_mse,
    mojom::MediaURLScheme url_scheme,
    mojom::MediaStreamType media_stream_type) {
  if (initialized_) {
    mojo::ReportBadMessage(kInvalidInitialize);
    return;
  }

  is_mse_ = is_mse;
  initialized_ = true;
  url_scheme_ = url_scheme;
  media_stream_type_ = media_stream_type;
}

void MediaMetricsProvider::OnError(PipelineStatus status) {
  DCHECK(initialized_);
  uma_info_.last_pipeline_status = status;
}

void MediaMetricsProvider::SetIsEME() {
  // This may be called before Initialize().
  uma_info_.is_eme = true;
}

void MediaMetricsProvider::SetTimeToMetadata(base::TimeDelta elapsed) {
  DCHECK(initialized_);
  DCHECK_EQ(time_to_metadata_, kNoTimestamp);
  time_to_metadata_ = elapsed;
}

void MediaMetricsProvider::SetTimeToFirstFrame(base::TimeDelta elapsed) {
  DCHECK(initialized_);
  DCHECK_EQ(time_to_first_frame_, kNoTimestamp);
  time_to_first_frame_ = elapsed;
}

void MediaMetricsProvider::SetTimeToPlayReady(base::TimeDelta elapsed) {
  DCHECK(initialized_);
  DCHECK_EQ(time_to_play_ready_, kNoTimestamp);
  time_to_play_ready_ = elapsed;
}

void MediaMetricsProvider::SetContainerName(
    container_names::MediaContainerName container_name) {
  DCHECK(initialized_);
  DCHECK(!container_name_.has_value());
  container_name_ = container_name;
}

void MediaMetricsProvider::SetRendererType(RendererType renderer_type) {
  renderer_type_ = renderer_type;
}

void MediaMetricsProvider::SetKeySystem(const std::string& key_system) {
  key_system_ = key_system;
}

void MediaMetricsProvider::SetIsHardwareSecure() {
  is_hardware_secure_ = true;
}

void MediaMetricsProvider::AcquireWatchTimeRecorder(
    mojom::PlaybackPropertiesPtr properties,
    mojo::PendingReceiver<mojom::WatchTimeRecorder> receiver) {
  if (!initialized_) {
    mojo::ReportBadMessage(kInvalidInitialize);
    return;
  }

  mojo::MakeSelfOwnedReceiver(
      std::make_unique<WatchTimeRecorder>(std::move(properties), source_id_,
                                          is_top_frame_, player_id_,
                                          record_playback_cb_),
      std::move(receiver));
}

void MediaMetricsProvider::AcquireVideoDecodeStatsRecorder(
    mojo::PendingReceiver<mojom::VideoDecodeStatsRecorder> receiver) {
  if (!initialized_) {
    mojo::ReportBadMessage(kInvalidInitialize);
    return;
  }

  if (!save_cb_) {
    DVLOG(3) << __func__ << " Ignoring request, SaveCallback is null";
    return;
  }

  mojo::MakeSelfOwnedReceiver(
      std::make_unique<VideoDecodeStatsRecorder>(save_cb_, source_id_, origin_,
                                                 is_top_frame_, player_id_),
      std::move(receiver));
}

void MediaMetricsProvider::AcquirePlaybackEventsRecorder(
    mojo::PendingReceiver<mojom::PlaybackEventsRecorder> receiver) {
#if defined(OS_FUCHSIA) || (BUILDFLAG(IS_CHROMECAST) && defined(OS_ANDROID))
  PlaybackEventsRecorder::Create(std::move(receiver));
#endif
}

void MediaMetricsProvider::AcquireLearningTaskController(
    const std::string& taskName,
    mojo::PendingReceiver<learning::mojom::LearningTaskController> receiver) {
  learning::LearningSession* session = learning_session_cb_.Run();
  if (!session) {
    DVLOG(3) << __func__ << " Ignoring request, unable to get LearningSession.";
    return;
  }

  auto controller = session->GetController(taskName);

  if (!controller) {
    DVLOG(3) << __func__ << " Ignoring request, no controller found for task: '"
             << taskName << "'.";
    return;
  }

  mojo::MakeSelfOwnedReceiver(
      std::make_unique<learning::MojoLearningTaskControllerService>(
          controller->GetLearningTask(), source_id_, std::move(controller)),
      std::move(receiver));
}

}  // namespace media
