// 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 "third_party/blink/renderer/controller/oom_intervention_impl.h"

#include <algorithm>
#include <utility>

#include "base/bind.h"
#include "base/debug/crash_logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.h"
#include "third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"

namespace blink {

namespace {
enum class OomInterventionState {
  // Initial value for a variable.
  None,
  // Before the intervention has been triggered.
  Before,
  // While the intervention is active.
  During,
  // After the intervention has triggered at least once.
  After
};
void UpdateStateCrashKey(OomInterventionState next_state) {
  static OomInterventionState current_state = OomInterventionState::None;
  // Once an intervention is trigger, the state shall never go back to the
  // Before state.
  if (next_state == OomInterventionState::Before &&
      current_state != OomInterventionState::None)
    return;
  if (current_state == next_state)
    return;
  current_state = next_state;
  static auto* crash_key = base::debug::AllocateCrashKeyString(
      "oom_intervention_state", base::debug::CrashKeySize::Size32);
  switch (current_state) {
    case OomInterventionState::None:
      base::debug::SetCrashKeyString(crash_key, "none");
      break;
    case OomInterventionState::Before:
      base::debug::SetCrashKeyString(crash_key, "before");
      break;
    case OomInterventionState::During:
      base::debug::SetCrashKeyString(crash_key, "during");
      break;
    case OomInterventionState::After:
      base::debug::SetCrashKeyString(crash_key, "after");
      break;
  }
}

void NavigateLocalAdsFrames(LocalFrame* frame) {
  // This navigates all the frames detected as an advertisement to about:blank.
  DCHECK(frame);
  for (Frame* child = frame->Tree().FirstChild(); child;
       child = child->Tree().TraverseNext(frame)) {
    if (auto* child_local_frame = DynamicTo<LocalFrame>(child)) {
      if (child_local_frame->IsAdSubframe()) {
        FrameLoadRequest request(frame->DomWindow(),
                                 ResourceRequest(BlankURL()));
        child_local_frame->Navigate(request, WebFrameLoadType::kStandard);
      }
    }
    // TODO(yuzus): Once AdsTracker for remote frames is implemented and OOPIF
    // is enabled on low-end devices, navigate remote ads as well.
  }
}

}  // namespace

// static
void OomInterventionImpl::Create(
    mojo::PendingReceiver<mojom::blink::OomIntervention> receiver) {
  mojo::MakeSelfOwnedReceiver(std::make_unique<OomInterventionImpl>(),
                              std::move(receiver));
}

OomInterventionImpl::OomInterventionImpl()
    : delayed_report_timer_(Thread::MainThread()->GetTaskRunner(),
                            this,
                            &OomInterventionImpl::TimerFiredUMAReport) {
  UpdateStateCrashKey(OomInterventionState::Before);
}

OomInterventionImpl::~OomInterventionImpl() {
  UpdateStateCrashKey(OomInterventionState::After);
  MemoryUsageMonitorInstance().RemoveObserver(this);
}

void OomInterventionImpl::StartDetection(
    mojo::PendingRemote<mojom::blink::OomInterventionHost> host,
    mojom::blink::DetectionArgsPtr detection_args,
    bool renderer_pause_enabled,
    bool navigate_ads_enabled,
    bool purge_v8_memory_enabled) {
  host_.Bind(std::move(host));

  detection_args_ = std::move(detection_args);
  renderer_pause_enabled_ = renderer_pause_enabled;
  navigate_ads_enabled_ = navigate_ads_enabled;
  purge_v8_memory_enabled_ = purge_v8_memory_enabled;

  MemoryUsageMonitorInstance().AddObserver(this);
}

MemoryUsageMonitor& OomInterventionImpl::MemoryUsageMonitorInstance() {
  return MemoryUsageMonitor::Instance();
}

void OomInterventionImpl::OnMemoryPing(MemoryUsage usage) {
  // Ignore pings without process memory usage information.
  if (std::isnan(usage.private_footprint_bytes) ||
      std::isnan(usage.swap_bytes) || std::isnan(usage.vm_size_bytes))
    return;
  Check(usage);
}

void OomInterventionImpl::Check(MemoryUsage usage) {
  DCHECK(host_);

  OomInterventionMetrics current_memory =
      CrashMemoryMetricsReporterImpl::MemoryUsageToMetrics(usage);

  bool oom_detected = false;

  oom_detected |= detection_args_->blink_workload_threshold > 0 &&
                  current_memory.current_blink_usage_kb * 1024 >
                      detection_args_->blink_workload_threshold;
  oom_detected |= detection_args_->private_footprint_threshold > 0 &&
                  current_memory.current_private_footprint_kb * 1024 >
                      detection_args_->private_footprint_threshold;
  oom_detected |=
      detection_args_->swap_threshold > 0 &&
      current_memory.current_swap_kb * 1024 > detection_args_->swap_threshold;
  oom_detected |= detection_args_->virtual_memory_thresold > 0 &&
                  current_memory.current_vm_size_kb * 1024 >
                      detection_args_->virtual_memory_thresold;

  // Report memory stats every second to send UMA.
  ReportMemoryStats(current_memory);

  if (oom_detected) {
    UpdateStateCrashKey(OomInterventionState::During);

    UMA_HISTOGRAM_MEMORY_MB(
        "Memory.Experimental.OomIntervention.V8UsageBefore",
        base::saturated_cast<int>(usage.v8_bytes / 1024 / 1024));

    if (navigate_ads_enabled_ || purge_v8_memory_enabled_) {
      for (const auto& page : Page::OrdinaryPages()) {
        for (Frame* frame = page->MainFrame(); frame;
             frame = frame->Tree().TraverseNext()) {
          auto* local_frame = DynamicTo<LocalFrame>(frame);
          if (!local_frame)
            continue;
          if (navigate_ads_enabled_)
            NavigateLocalAdsFrames(local_frame);
          if (purge_v8_memory_enabled_)
            local_frame->ForciblyPurgeV8Memory();
        }
      }
    }

    if (renderer_pause_enabled_) {
      // The ScopedPagePauser is destroyed when the intervention is declined and
      // mojo strong binding is disconnected.
      pauser_.reset(new ScopedPagePauser);
    }

    host_->OnHighMemoryUsage();
    MemoryUsageMonitorInstance().RemoveObserver(this);
    // Send memory pressure notification to trigger GC.
    Thread::MainThread()->GetTaskRunner()->PostTask(FROM_HERE,
                                                    base::BindOnce(&TriggerGC));
    // Notify V8GCForContextDispose that page navigation gc is needed when
    // intervention runs, as it indicates that memory usage is high.
    V8GCForContextDispose::Instance().SetForcePageNavigationGC();

    // Report the memory impact of intervention after 10, 20, 30 seconds.
    metrics_at_intervention_ = current_memory;
    number_of_report_needed_ = 3;
    delayed_report_timer_.StartRepeating(base::TimeDelta::FromSeconds(10),
                                         FROM_HERE);
  }
}

void OomInterventionImpl::ReportMemoryStats(
    OomInterventionMetrics& current_memory) {
  UMA_HISTOGRAM_MEMORY_MB(
      "Memory.Experimental.OomIntervention.RendererBlinkUsage",
      base::saturated_cast<base::Histogram::Sample>(
          current_memory.current_blink_usage_kb / 1024));
  UMA_HISTOGRAM_MEMORY_LARGE_MB(
      "Memory.Experimental.OomIntervention."
      "RendererPrivateMemoryFootprint",
      base::saturated_cast<base::Histogram::Sample>(
          current_memory.current_private_footprint_kb / 1024));
  UMA_HISTOGRAM_MEMORY_MB(
      "Memory.Experimental.OomIntervention.RendererSwapFootprint",
      base::saturated_cast<base::Histogram::Sample>(
          current_memory.current_swap_kb / 1024));
  UMA_HISTOGRAM_MEMORY_LARGE_MB(
      "Memory.Experimental.OomIntervention.RendererVmSize",
      base::saturated_cast<base::Histogram::Sample>(
          current_memory.current_vm_size_kb / 1024));
}

int ToMemoryUsageDeltaSample(uint64_t after_kb, uint64_t before_kb) {
  int delta_mb = (base::saturated_cast<int>(before_kb) -
                  base::saturated_cast<int>(after_kb)) /
                 1024;
  return std::min(std::max(delta_mb, -500), 500);
}

void OomInterventionImpl::TimerFiredUMAReport(TimerBase*) {
  MemoryUsage usage = MemoryUsageMonitorInstance().GetCurrentMemoryUsage();
  OomInterventionMetrics current_memory =
      CrashMemoryMetricsReporterImpl::MemoryUsageToMetrics(usage);
  int blink_usage_delta =
      ToMemoryUsageDeltaSample(current_memory.current_blink_usage_kb,
                               metrics_at_intervention_.current_blink_usage_kb);
  int private_footprint_delta = ToMemoryUsageDeltaSample(
      current_memory.current_private_footprint_kb,
      metrics_at_intervention_.current_private_footprint_kb);
  int v8_usage_mb = base::saturated_cast<int>(usage.v8_bytes / 1024 / 1024);
  switch (number_of_report_needed_--) {
    case 3:
      UMA_HISTOGRAM_MEMORY_MB(
          "Memory.Experimental.OomIntervention.V8UsageAfter10secs",
          v8_usage_mb);
      base::UmaHistogramSparse(
          "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter10secs2",
          blink_usage_delta);
      base::UmaHistogramSparse(
          "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter10secs2",
          private_footprint_delta);
      break;
    case 2:
      UMA_HISTOGRAM_MEMORY_MB(
          "Memory.Experimental.OomIntervention.V8UsageAfter20secs",
          v8_usage_mb);
      base::UmaHistogramSparse(
          "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter20secs2",
          blink_usage_delta);
      base::UmaHistogramSparse(
          "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter20secs2",
          private_footprint_delta);
      break;
    case 1:
      UMA_HISTOGRAM_MEMORY_MB(
          "Memory.Experimental.OomIntervention.V8UsageAfter30secs",
          v8_usage_mb);
      base::UmaHistogramSparse(
          "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter30secs2",
          blink_usage_delta);
      base::UmaHistogramSparse(
          "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter30secs2",
          private_footprint_delta);
      delayed_report_timer_.Stop();
      break;
  }
}

void OomInterventionImpl::TriggerGC() {
  V8PerIsolateData::MainThreadIsolate()->MemoryPressureNotification(
      v8::MemoryPressureLevel::kCritical);
}

}  // namespace blink
