// 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 "platform/scheduler/renderer/renderer_metrics_helper.h"

#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "platform/instrumentation/resource_coordinator/RendererResourceCoordinator.h"
#include "platform/scheduler/public/frame_scheduler.h"
#include "platform/scheduler/renderer/renderer_scheduler_impl.h"
#include "public/platform/scheduler/renderer_process_type.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"

namespace blink {
namespace scheduler {

#define DURATION_PER_QUEUE_TYPE_METRIC_NAME \
  "RendererScheduler.TaskDurationPerQueueType2"
#define COUNT_PER_QUEUE_TYPE_METRIC_NAME \
  "RendererScheduler.TaskCountPerQueueType"
#define MAIN_THREAD_LOAD_METRIC_NAME "RendererScheduler.RendererMainThreadLoad5"
#define EXTENSIONS_MAIN_THREAD_LOAD_METRIC_NAME \
  MAIN_THREAD_LOAD_METRIC_NAME ".Extension"
#define DURATION_PER_FRAME_TYPE_METRIC_NAME \
  "RendererScheduler.TaskDurationPerFrameType2"
#define DURATION_PER_TASK_TYPE_METRIC_NAME \
  "RendererScheduler.TaskDurationPerTaskType"
#define COUNT_PER_FRAME_METRIC_NAME "RendererScheduler.TaskCountPerFrameType"
#define DURATION_PER_TASK_USE_CASE_NAME \
  "RendererScheduler.TaskDurationPerUseCase"

enum class MainThreadTaskLoadState { kLow, kHigh, kUnknown };

namespace {

constexpr base::TimeDelta kThreadLoadTrackerReportingInterval =
    base::TimeDelta::FromSeconds(1);
constexpr base::TimeDelta kLongIdlePeriodDiscardingThreshold =
    base::TimeDelta::FromMinutes(3);

}  // namespace

RendererMetricsHelper::PerQueueTypeDurationReporters::
    PerQueueTypeDurationReporters()
    : overall(DURATION_PER_QUEUE_TYPE_METRIC_NAME),
      foreground(DURATION_PER_QUEUE_TYPE_METRIC_NAME ".Foreground"),
      foreground_first_minute(DURATION_PER_QUEUE_TYPE_METRIC_NAME
                              ".Foreground.FirstMinute"),
      foreground_second_minute(DURATION_PER_QUEUE_TYPE_METRIC_NAME
                               ".Foreground.SecondMinute"),
      foreground_third_minute(DURATION_PER_QUEUE_TYPE_METRIC_NAME
                              ".Foreground.ThirdMinute"),
      foreground_after_third_minute(DURATION_PER_QUEUE_TYPE_METRIC_NAME
                                    ".Foreground.AfterThirdMinute"),
      background(DURATION_PER_QUEUE_TYPE_METRIC_NAME ".Background"),
      background_first_minute(DURATION_PER_QUEUE_TYPE_METRIC_NAME
                              ".Background.FirstMinute"),
      background_second_minute(DURATION_PER_QUEUE_TYPE_METRIC_NAME
                               ".Background.SecondMinute"),
      background_third_minute(DURATION_PER_QUEUE_TYPE_METRIC_NAME
                              ".Background.ThirdMinute"),
      background_fourth_minute(DURATION_PER_QUEUE_TYPE_METRIC_NAME
                               ".Background.FourthMinute"),
      background_fifth_minute(DURATION_PER_QUEUE_TYPE_METRIC_NAME
                              ".Background.FifthMinute"),
      background_after_fifth_minute(DURATION_PER_QUEUE_TYPE_METRIC_NAME
                                    ".Background.AfterFifthMinute"),
      background_keep_active_after_fifth_minute(
          DURATION_PER_QUEUE_TYPE_METRIC_NAME
          ".Background.KeepAlive.AfterFifthMinute"),
      hidden(DURATION_PER_QUEUE_TYPE_METRIC_NAME ".Hidden"),
      visible(DURATION_PER_QUEUE_TYPE_METRIC_NAME ".Visible"),
      hidden_music(DURATION_PER_QUEUE_TYPE_METRIC_NAME ".HiddenMusic") {}

RendererMetricsHelper::RendererMetricsHelper(
    RendererSchedulerImpl* renderer_scheduler,
    base::TimeTicks now,
    bool renderer_backgrounded)
    : MetricsHelper(WebThreadType::kMainThread),
      renderer_scheduler_(renderer_scheduler),
      main_thread_load_tracker_(
          now,
          base::BindRepeating(&RendererMetricsHelper::RecordMainThreadTaskLoad,
                              base::Unretained(this)),
          kThreadLoadTrackerReportingInterval),
      background_main_thread_load_tracker_(
          now,
          base::BindRepeating(
              &RendererMetricsHelper::RecordBackgroundMainThreadTaskLoad,
              base::Unretained(this)),
          kThreadLoadTrackerReportingInterval),
      foreground_main_thread_load_tracker_(
          now,
          base::BindRepeating(
              &RendererMetricsHelper::RecordForegroundMainThreadTaskLoad,
              base::Unretained(this)),
          kThreadLoadTrackerReportingInterval),
      per_frame_status_duration_reporter_(DURATION_PER_FRAME_TYPE_METRIC_NAME),
      per_task_type_duration_reporter_(DURATION_PER_TASK_TYPE_METRIC_NAME),
      no_use_case_per_task_type_duration_reporter_(
          DURATION_PER_TASK_TYPE_METRIC_NAME ".UseCaseNone"),
      loading_per_task_type_duration_reporter_(
          DURATION_PER_TASK_TYPE_METRIC_NAME ".UseCaseLoading"),
      input_handling_per_task_type_duration_reporter_(
          DURATION_PER_TASK_TYPE_METRIC_NAME ".UseCaseInputHandling"),
      foreground_per_task_type_duration_reporter_(
          DURATION_PER_TASK_TYPE_METRIC_NAME ".Foreground"),
      background_per_task_type_duration_reporter_(
          DURATION_PER_TASK_TYPE_METRIC_NAME ".Background"),
      per_task_use_case_duration_reporter_(DURATION_PER_TASK_USE_CASE_NAME),
      main_thread_task_load_state_(MainThreadTaskLoadState::kUnknown) {
  main_thread_load_tracker_.Resume(now);
  if (renderer_backgrounded) {
    background_main_thread_load_tracker_.Resume(now);
  } else {
    foreground_main_thread_load_tracker_.Resume(now);
  }
}

RendererMetricsHelper::~RendererMetricsHelper() = default;

void RendererMetricsHelper::OnRendererForegrounded(base::TimeTicks now) {
  foreground_main_thread_load_tracker_.Resume(now);
  background_main_thread_load_tracker_.Pause(now);
}

void RendererMetricsHelper::OnRendererBackgrounded(base::TimeTicks now) {
  foreground_main_thread_load_tracker_.Pause(now);
  background_main_thread_load_tracker_.Resume(now);
}

void RendererMetricsHelper::OnRendererShutdown(base::TimeTicks now) {
  foreground_main_thread_load_tracker_.RecordIdle(now);
  background_main_thread_load_tracker_.RecordIdle(now);
  main_thread_load_tracker_.RecordIdle(now);
}

void RendererMetricsHelper::ResetForTest(base::TimeTicks now) {
  main_thread_load_tracker_ = ThreadLoadTracker(
      now,
      base::BindRepeating(&RendererMetricsHelper::RecordMainThreadTaskLoad,
                          base::Unretained(this)),
      kThreadLoadTrackerReportingInterval);

  background_main_thread_load_tracker_ = ThreadLoadTracker(
      now,
      base::BindRepeating(
          &RendererMetricsHelper::RecordBackgroundMainThreadTaskLoad,
          base::Unretained(this)),
      kThreadLoadTrackerReportingInterval);

  foreground_main_thread_load_tracker_ = ThreadLoadTracker(
      now,
      base::BindRepeating(
          &RendererMetricsHelper::RecordForegroundMainThreadTaskLoad,
          base::Unretained(this)),
      kThreadLoadTrackerReportingInterval);
}

namespace {

// Calculates the length of the intersection of two given time intervals.
base::TimeDelta DurationOfIntervalOverlap(base::TimeTicks start1,
                                          base::TimeTicks end1,
                                          base::TimeTicks start2,
                                          base::TimeTicks end2) {
  DCHECK_LE(start1, end1);
  DCHECK_LE(start2, end2);
  return std::max(std::min(end1, end2) - std::max(start1, start2),
                  base::TimeDelta());
}

}  // namespace

void RendererMetricsHelper::RecordTaskMetrics(
    MainThreadTaskQueue* queue,
    const TaskQueue::Task& task,
    base::TimeTicks start_time,
    base::TimeTicks end_time,
    base::Optional<base::TimeDelta> thread_time) {
  if (ShouldDiscardTask(queue, task, start_time, end_time, thread_time))
    return;

  MetricsHelper::RecordCommonTaskMetrics(queue, task, start_time, end_time,
                                         thread_time);

  MainThreadTaskQueue::QueueType queue_type =
      queue ? queue->queue_type() : MainThreadTaskQueue::QueueType::kDetached;
  base::TimeDelta duration = end_time - start_time;

  // Discard anomalously long idle periods.
  if (last_reported_task_ && start_time - last_reported_task_.value() >
                                 kLongIdlePeriodDiscardingThreshold) {
    main_thread_load_tracker_.Reset(end_time);
    foreground_main_thread_load_tracker_.Reset(end_time);
    background_main_thread_load_tracker_.Reset(end_time);
    return;
  }

  last_reported_task_ = end_time;

  UMA_HISTOGRAM_CUSTOM_COUNTS("RendererScheduler.TaskTime2",
                              duration.InMicroseconds(), 1, 1000 * 1000, 50);

  // We want to measure thread time here, but for efficiency reasons
  // we stick with wall time.
  main_thread_load_tracker_.RecordTaskTime(start_time, end_time);
  foreground_main_thread_load_tracker_.RecordTaskTime(start_time, end_time);
  background_main_thread_load_tracker_.RecordTaskTime(start_time, end_time);

  UMA_HISTOGRAM_ENUMERATION(COUNT_PER_QUEUE_TYPE_METRIC_NAME, queue_type,
                            MainThreadTaskQueue::QueueType::kCount);

  if (duration >= base::TimeDelta::FromMilliseconds(16)) {
    UMA_HISTOGRAM_ENUMERATION(
        COUNT_PER_QUEUE_TYPE_METRIC_NAME ".LongerThan16ms", queue_type,
        MainThreadTaskQueue::QueueType::kCount);
  }

  if (duration >= base::TimeDelta::FromMilliseconds(50)) {
    UMA_HISTOGRAM_ENUMERATION(
        COUNT_PER_QUEUE_TYPE_METRIC_NAME ".LongerThan50ms", queue_type,
        MainThreadTaskQueue::QueueType::kCount);
  }

  if (duration >= base::TimeDelta::FromMilliseconds(100)) {
    UMA_HISTOGRAM_ENUMERATION(
        COUNT_PER_QUEUE_TYPE_METRIC_NAME ".LongerThan100ms", queue_type,
        MainThreadTaskQueue::QueueType::kCount);
  }

  if (duration >= base::TimeDelta::FromMilliseconds(150)) {
    UMA_HISTOGRAM_ENUMERATION(
        COUNT_PER_QUEUE_TYPE_METRIC_NAME ".LongerThan150ms", queue_type,
        MainThreadTaskQueue::QueueType::kCount);
  }

  if (duration >= base::TimeDelta::FromSeconds(1)) {
    UMA_HISTOGRAM_ENUMERATION(COUNT_PER_QUEUE_TYPE_METRIC_NAME ".LongerThan1s",
                              queue_type,
                              MainThreadTaskQueue::QueueType::kCount);
  }

  per_queue_type_reporters_.overall.RecordTask(queue_type, duration);

  TaskType task_type = static_cast<TaskType>(task.task_type());
  per_task_type_duration_reporter_.RecordTask(task_type, duration);

  if (renderer_scheduler_->main_thread_only().renderer_backgrounded) {
    per_queue_type_reporters_.background.RecordTask(queue_type, duration);

    // Collect detailed breakdown for first five minutes given that we stop
    // timers on mobile after five minutes.
    base::TimeTicks backgrounded_at =
        renderer_scheduler_->main_thread_only().background_status_changed_at;

    per_queue_type_reporters_.background_first_minute.RecordTask(
        queue_type, DurationOfIntervalOverlap(
                        start_time, end_time, backgrounded_at,
                        backgrounded_at + base::TimeDelta::FromMinutes(1)));

    per_queue_type_reporters_.background_second_minute.RecordTask(
        queue_type, DurationOfIntervalOverlap(
                        start_time, end_time,
                        backgrounded_at + base::TimeDelta::FromMinutes(1),
                        backgrounded_at + base::TimeDelta::FromMinutes(2)));

    per_queue_type_reporters_.background_third_minute.RecordTask(
        queue_type, DurationOfIntervalOverlap(
                        start_time, end_time,
                        backgrounded_at + base::TimeDelta::FromMinutes(2),
                        backgrounded_at + base::TimeDelta::FromMinutes(3)));

    per_queue_type_reporters_.background_fourth_minute.RecordTask(
        queue_type, DurationOfIntervalOverlap(
                        start_time, end_time,
                        backgrounded_at + base::TimeDelta::FromMinutes(3),
                        backgrounded_at + base::TimeDelta::FromMinutes(4)));

    per_queue_type_reporters_.background_fifth_minute.RecordTask(
        queue_type, DurationOfIntervalOverlap(
                        start_time, end_time,
                        backgrounded_at + base::TimeDelta::FromMinutes(4),
                        backgrounded_at + base::TimeDelta::FromMinutes(5)));

    per_queue_type_reporters_.background_after_fifth_minute.RecordTask(
        queue_type,
        DurationOfIntervalOverlap(
            start_time, end_time,
            backgrounded_at + base::TimeDelta::FromMinutes(5),
            std::max(backgrounded_at + base::TimeDelta::FromMinutes(5),
                     end_time)));

    if (renderer_scheduler_->main_thread_only().keep_active_fetch_or_worker) {
      per_queue_type_reporters_.background_keep_active_after_fifth_minute
          .RecordTask(
              queue_type,
              DurationOfIntervalOverlap(
                  start_time, end_time,
                  backgrounded_at + base::TimeDelta::FromMinutes(5),
                  std::max(backgrounded_at + base::TimeDelta::FromMinutes(5),
                           end_time)));
    }

    background_per_task_type_duration_reporter_.RecordTask(task_type, duration);
  } else {
    per_queue_type_reporters_.foreground.RecordTask(queue_type, duration);

    // For foreground tabs we do not expect such a notable difference as it is
    // the case with background tabs, so we limit breakdown to three minutes.
    base::TimeTicks foregrounded_at =
        renderer_scheduler_->main_thread_only().background_status_changed_at;

    per_queue_type_reporters_.foreground_first_minute.RecordTask(
        queue_type, DurationOfIntervalOverlap(
                        start_time, end_time, foregrounded_at,
                        foregrounded_at + base::TimeDelta::FromMinutes(1)));

    per_queue_type_reporters_.foreground_second_minute.RecordTask(
        queue_type, DurationOfIntervalOverlap(
                        start_time, end_time,
                        foregrounded_at + base::TimeDelta::FromMinutes(1),
                        foregrounded_at + base::TimeDelta::FromMinutes(2)));

    per_queue_type_reporters_.foreground_third_minute.RecordTask(
        queue_type, DurationOfIntervalOverlap(
                        start_time, end_time,
                        foregrounded_at + base::TimeDelta::FromMinutes(2),
                        foregrounded_at + base::TimeDelta::FromMinutes(3)));

    per_queue_type_reporters_.foreground_after_third_minute.RecordTask(
        queue_type,
        DurationOfIntervalOverlap(
            start_time, end_time,
            foregrounded_at + base::TimeDelta::FromMinutes(3),
            std::max(foregrounded_at + base::TimeDelta::FromMinutes(3),
                     end_time)));

    foreground_per_task_type_duration_reporter_.RecordTask(task_type, duration);
  }

  if (renderer_scheduler_->main_thread_only().renderer_hidden) {
    per_queue_type_reporters_.hidden.RecordTask(queue_type, duration);

    if (renderer_scheduler_->ShouldDisableThrottlingBecauseOfAudio(
            start_time)) {
      per_queue_type_reporters_.hidden_music.RecordTask(queue_type, duration);
    }
  } else {
    per_queue_type_reporters_.visible.RecordTask(queue_type, duration);
  }

  FrameStatus frame_status =
      GetFrameStatus(queue ? queue->GetFrameScheduler() : nullptr);
  per_frame_status_duration_reporter_.RecordTask(frame_status, duration);
  UMA_HISTOGRAM_ENUMERATION(COUNT_PER_FRAME_METRIC_NAME, frame_status,
                            FrameStatus::kCount);
  if (duration >= base::TimeDelta::FromMilliseconds(16)) {
    UMA_HISTOGRAM_ENUMERATION(COUNT_PER_FRAME_METRIC_NAME ".LongerThan16ms",
                              frame_status, FrameStatus::kCount);
  }

  if (duration >= base::TimeDelta::FromMilliseconds(50)) {
    UMA_HISTOGRAM_ENUMERATION(COUNT_PER_FRAME_METRIC_NAME ".LongerThan50ms",
                              frame_status, FrameStatus::kCount);
  }

  if (duration >= base::TimeDelta::FromMilliseconds(100)) {
    UMA_HISTOGRAM_ENUMERATION(COUNT_PER_FRAME_METRIC_NAME ".LongerThan100ms",
                              frame_status, FrameStatus::kCount);
  }

  if (duration >= base::TimeDelta::FromMilliseconds(150)) {
    UMA_HISTOGRAM_ENUMERATION(COUNT_PER_FRAME_METRIC_NAME ".LongerThan150ms",
                              frame_status, FrameStatus::kCount);
  }

  if (duration >= base::TimeDelta::FromSeconds(1)) {
    UMA_HISTOGRAM_ENUMERATION(COUNT_PER_FRAME_METRIC_NAME ".LongerThan1s",
                              frame_status, FrameStatus::kCount);
  }

  UseCase use_case = renderer_scheduler_->main_thread_only().current_use_case;
  per_task_use_case_duration_reporter_.RecordTask(use_case, duration);
  if (use_case == UseCase::kNone) {
    no_use_case_per_task_type_duration_reporter_.RecordTask(task_type,
                                                            duration);
  } else if (use_case == UseCase::kLoading) {
    loading_per_task_type_duration_reporter_.RecordTask(task_type, duration);
  } else {
    input_handling_per_task_type_duration_reporter_.RecordTask(task_type,
                                                               duration);
  }
}

void RendererMetricsHelper::RecordMainThreadTaskLoad(base::TimeTicks time,
                                                     double load) {
  int load_percentage = static_cast<int>(load * 100);
  DCHECK_LE(load_percentage, 100);

  if (::resource_coordinator::IsPageAlmostIdleSignalEnabled()) {
    static const int main_thread_task_load_low_threshold =
        ::resource_coordinator::GetMainThreadTaskLoadLowThreshold();

    // Avoid sending duplicate IPCs when the state doesn't change.
    if (load_percentage <= main_thread_task_load_low_threshold &&
        main_thread_task_load_state_ != MainThreadTaskLoadState::kLow) {
      RendererResourceCoordinator::Get().SetMainThreadTaskLoadIsLow(true);
      main_thread_task_load_state_ = MainThreadTaskLoadState::kLow;
    } else if (load_percentage > main_thread_task_load_low_threshold &&
               main_thread_task_load_state_ != MainThreadTaskLoadState::kHigh) {
      RendererResourceCoordinator::Get().SetMainThreadTaskLoadIsLow(false);
      main_thread_task_load_state_ = MainThreadTaskLoadState::kHigh;
    }
  }

  UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME, load_percentage);

  if (renderer_scheduler_->main_thread_only().process_type ==
      RendererProcessType::kExtensionRenderer) {
    UMA_HISTOGRAM_PERCENTAGE(EXTENSIONS_MAIN_THREAD_LOAD_METRIC_NAME,
                             load_percentage);
  }

  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
                 "RendererScheduler.RendererMainThreadLoad", load_percentage);
}

void RendererMetricsHelper::RecordForegroundMainThreadTaskLoad(
    base::TimeTicks time,
    double load) {
  int load_percentage = static_cast<int>(load * 100);
  DCHECK_LE(load_percentage, 100);

  switch (renderer_scheduler_->main_thread_only().process_type) {
    case RendererProcessType::kExtensionRenderer:
      UMA_HISTOGRAM_PERCENTAGE(EXTENSIONS_MAIN_THREAD_LOAD_METRIC_NAME
                               ".Foreground",
                               load_percentage);
      break;
    case RendererProcessType::kRenderer:
      UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME ".Foreground",
                               load_percentage);

      if (time - renderer_scheduler_->main_thread_only()
                     .background_status_changed_at >
          base::TimeDelta::FromMinutes(1)) {
        UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME
                                 ".Foreground.AfterFirstMinute",
                                 load_percentage);
      }
      break;
  }

  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
                 "RendererScheduler.RendererMainThreadLoad.Foreground",
                 load_percentage);
}

void RendererMetricsHelper::RecordBackgroundMainThreadTaskLoad(
    base::TimeTicks time,
    double load) {
  int load_percentage = static_cast<int>(load * 100);
  DCHECK_LE(load_percentage, 100);

  switch (renderer_scheduler_->main_thread_only().process_type) {
    case RendererProcessType::kExtensionRenderer:
      UMA_HISTOGRAM_PERCENTAGE(EXTENSIONS_MAIN_THREAD_LOAD_METRIC_NAME
                               ".Background",
                               load_percentage);
      break;
    case RendererProcessType::kRenderer:
      UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME ".Background",
                               load_percentage);

      if (time - renderer_scheduler_->main_thread_only()
                     .background_status_changed_at >
          base::TimeDelta::FromMinutes(1)) {
        UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME
                                 ".Background.AfterFirstMinute",
                                 load_percentage);
      }
      break;
  }

  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
                 "RendererScheduler.RendererMainThreadLoad.Background",
                 load_percentage);
}

// static
void RendererMetricsHelper::RecordBackgroundedTransition(
    BackgroundedRendererTransition transition) {
  UMA_HISTOGRAM_ENUMERATION("RendererScheduler.BackgroundedRendererTransition",
                            transition, BackgroundedRendererTransition::kCount);
}
}  // namespace scheduler
}  // namespace blink
