// Copyright 2015 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 "components/page_load_metrics/renderer/metrics_render_frame_observer.h"

#include <string>
#include <utility>

#include "base/memory/ptr_util.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "components/page_load_metrics/renderer/page_timing_metrics_sender.h"
#include "components/page_load_metrics/renderer/page_timing_sender.h"
#include "content/public/renderer/render_frame.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/loader/resource_type_util.h"
#include "third_party/blink/public/common/mobile_metrics/mobile_friendliness.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_document_loader.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_performance.h"
#include "url/gurl.h"

namespace page_load_metrics {

namespace {

base::TimeDelta ClampDelta(double event, double start) {
  if (event - start < 0)
    event = start;
  return base::Time::FromDoubleT(event) - base::Time::FromDoubleT(start);
}

base::TimeTicks ClampToStart(base::TimeTicks event, base::TimeTicks start) {
  return event < start ? start : event;
}

class MojoPageTimingSender : public PageTimingSender {
 public:
  explicit MojoPageTimingSender(content::RenderFrame* render_frame,
                                bool limited_sending_mode)
      : limited_sending_mode_(limited_sending_mode) {
    DCHECK(render_frame);
    render_frame->GetRemoteAssociatedInterfaces()->GetInterface(
        &page_load_metrics_);
  }

  ~MojoPageTimingSender() override = default;

  void SendTiming(const mojom::PageLoadTimingPtr& timing,
                  const mojom::FrameMetadataPtr& metadata,
                  const std::vector<blink::UseCounterFeature>& new_features,
                  std::vector<mojom::ResourceDataUpdatePtr> resources,
                  const mojom::FrameRenderDataUpdate& render_data,
                  const mojom::CpuTimingPtr& cpu_timing,
                  mojom::DeferredResourceCountsPtr new_deferred_resource_data,
                  mojom::InputTimingPtr input_timing_delta,
                  const absl::optional<blink::MobileFriendliness>&
                      mobile_friendliness) override {
    DCHECK(page_load_metrics_);
    page_load_metrics_->UpdateTiming(
        limited_sending_mode_ ? CreatePageLoadTiming() : timing->Clone(),
        metadata->Clone(), new_features, std::move(resources),
        render_data.Clone(), cpu_timing->Clone(),
        std::move(new_deferred_resource_data), std::move(input_timing_delta),
        std::move(mobile_friendliness));
  }

  void SetUpSmoothnessReporting(
      base::ReadOnlySharedMemoryRegion shared_memory) override {
    DCHECK(page_load_metrics_);
    page_load_metrics_->SetUpSharedMemoryForSmoothness(
        std::move(shared_memory));
  }

 private:
  // Indicates that this sender should not send timing updates or frame render
  // data updates.
  // TODO(https://crbug.com/1097127): When timing updates are handled for cases
  // where we have a subframe document and no committed navigation, this can be
  // removed.
  bool limited_sending_mode_ = false;

  // Use associated interface to make sure mojo messages are ordered with regard
  // to legacy IPC messages.
  mojo::AssociatedRemote<mojom::PageLoadMetrics> page_load_metrics_;
};

}  //  namespace

MetricsRenderFrameObserver::MetricsRenderFrameObserver(
    content::RenderFrame* render_frame)
    : content::RenderFrameObserver(render_frame) {}

MetricsRenderFrameObserver::~MetricsRenderFrameObserver() {
  if (page_timing_metrics_sender_)
    page_timing_metrics_sender_->SendLatest();
}

void MetricsRenderFrameObserver::DidChangePerformanceTiming() {
  SendMetrics();
}

void MetricsRenderFrameObserver::DidObserveInputDelay(
    base::TimeDelta input_delay) {
  if (!page_timing_metrics_sender_ || HasNoRenderFrame()) {
    return;
  }
  page_timing_metrics_sender_->DidObserveInputDelay(input_delay);
}

void MetricsRenderFrameObserver::DidObserveUserInteraction(
    base::TimeDelta max_event_duration,
    base::TimeDelta total_event_duration,
    blink::UserInteractionType interaction_type) {
  if (!page_timing_metrics_sender_ || HasNoRenderFrame()) {
    return;
  }
  page_timing_metrics_sender_->DidObserveUserInteraction(
      max_event_duration, total_event_duration, interaction_type);
}

void MetricsRenderFrameObserver::DidChangeCpuTiming(base::TimeDelta time) {
  if (!page_timing_metrics_sender_)
    return;
  if (HasNoRenderFrame())
    return;
  page_timing_metrics_sender_->UpdateCpuTiming(time);
}

void MetricsRenderFrameObserver::DidObserveLoadingBehavior(
    blink::LoadingBehaviorFlag behavior) {
  if (page_timing_metrics_sender_)
    page_timing_metrics_sender_->DidObserveLoadingBehavior(behavior);
}

void MetricsRenderFrameObserver::DidObserveNewFeatureUsage(
    const blink::UseCounterFeature& feature) {
  if (page_timing_metrics_sender_)
    page_timing_metrics_sender_->DidObserveNewFeatureUsage(feature);
}

void MetricsRenderFrameObserver::DidObserveLayoutShift(
    double score,
    bool after_input_or_scroll) {
  if (page_timing_metrics_sender_)
    page_timing_metrics_sender_->DidObserveLayoutShift(score,
                                                       after_input_or_scroll);
}

void MetricsRenderFrameObserver::DidObserveLayoutNg(
    uint32_t all_block_count,
    uint32_t ng_block_count,
    uint32_t all_call_count,
    uint32_t ng_call_count,
    uint32_t flexbox_ng_block_count,
    uint32_t grid_ng_block_count) {
  if (page_timing_metrics_sender_)
    page_timing_metrics_sender_->DidObserveLayoutNg(
        all_block_count, ng_block_count, all_call_count, ng_call_count,
        flexbox_ng_block_count, grid_ng_block_count);
}

void MetricsRenderFrameObserver::DidObserveLazyLoadBehavior(
    blink::WebLocalFrameClient::LazyLoadBehavior lazy_load_behavior) {
  if (page_timing_metrics_sender_)
    page_timing_metrics_sender_->DidObserveLazyLoadBehavior(lazy_load_behavior);
}

void MetricsRenderFrameObserver::DidStartResponse(
    const GURL& response_url,
    int request_id,
    const network::mojom::URLResponseHead& response_head,
    network::mojom::RequestDestination request_destination) {
  if (provisional_frame_resource_data_use_ &&
      blink::IsRequestDestinationFrame(request_destination)) {
    // TODO(rajendrant): This frame request might start before the provisional
    // load starts, and data use of the frame request might be missed in that
    // case. There should be a guarantee that DidStartProvisionalLoad be called
    // before DidStartResponse for the frame request.
    provisional_frame_resource_data_use_->DidStartResponse(
        response_url, request_id, response_head, request_destination);
  } else if (page_timing_metrics_sender_) {
    page_timing_metrics_sender_->DidStartResponse(
        response_url, request_id, response_head, request_destination);
    UpdateResourceMetadata(request_id);
  }
}

void MetricsRenderFrameObserver::DidCompleteResponse(
    int request_id,
    const network::URLLoaderCompletionStatus& status) {
  if (provisional_frame_resource_data_use_ &&
      provisional_frame_resource_data_use_->resource_id() == request_id) {
    provisional_frame_resource_data_use_->DidCompleteResponse(status);
  } else if (page_timing_metrics_sender_) {
    page_timing_metrics_sender_->DidCompleteResponse(request_id, status);
    MaybeSetCompletedBeforeFCP(request_id);
    UpdateResourceMetadata(request_id);
  }
}

void MetricsRenderFrameObserver::DidCancelResponse(int request_id) {
  if (provisional_frame_resource_data_use_ &&
      provisional_frame_resource_data_use_->resource_id() == request_id) {
    provisional_frame_resource_data_use_.reset();
  } else if (page_timing_metrics_sender_) {
    page_timing_metrics_sender_->DidCancelResponse(request_id);
    UpdateResourceMetadata(request_id);
  }
}

void MetricsRenderFrameObserver::DidReceiveTransferSizeUpdate(
    int request_id,
    int received_data_length) {
  if (provisional_frame_resource_data_use_ &&
      provisional_frame_resource_data_use_->resource_id() == request_id) {
    provisional_frame_resource_data_use_->DidReceiveTransferSizeUpdate(
        received_data_length);
  } else if (page_timing_metrics_sender_) {
    page_timing_metrics_sender_->DidReceiveTransferSizeUpdate(
        request_id, received_data_length);
    UpdateResourceMetadata(request_id);
  }
}

void MetricsRenderFrameObserver::DidLoadResourceFromMemoryCache(
    const GURL& response_url,
    int request_id,
    int64_t encoded_body_length,
    const std::string& mime_type,
    bool from_archive) {
  // Resources from archives, such as subresources from a MHTML archive, do not
  // have valid request ids and should not be reported to PLM.
  if (from_archive)
    return;

  // A provisional frame resource cannot be serviced from the memory cache, so
  // we do not need to check |provisional_frame_resource_data_use_|.
  if (page_timing_metrics_sender_) {
    page_timing_metrics_sender_->DidLoadResourceFromMemoryCache(
        response_url, request_id, encoded_body_length, mime_type);
    MaybeSetCompletedBeforeFCP(request_id);
    UpdateResourceMetadata(request_id);
  }
}

void MetricsRenderFrameObserver::WillDetach() {
  if (page_timing_metrics_sender_) {
    page_timing_metrics_sender_->SendLatest();
    page_timing_metrics_sender_.reset();
  }
}

void MetricsRenderFrameObserver::DidStartNavigation(
    const GURL& url,
    absl::optional<blink::WebNavigationType> navigation_type) {
  // Send current metrics, as we might create a new RenderFrame later due to
  // this navigation (that might end up in a different process entirely, and
  // won't notify us until the current RenderFrameHost in the browser changed).
  // If that happens, it will be too late to send the metrics from WillDetach
  // or the destructor, because the browser ignores metrics update from
  // non-current RenderFrameHosts. See crbug.com/1150242 for more details.
  // TODO(crbug.com/1150242): Remove this when we have the full fix for the bug.
  if (page_timing_metrics_sender_)
    page_timing_metrics_sender_->SendLatest();
}

void MetricsRenderFrameObserver::DidSetPageLifecycleState() {
  // Send current metrics, as this RenderFrame might be replaced by a new
  // RenderFrame or its process might be killed, and this might be the last
  // point we can send the metrics to the browser. See crbug.com/1150242 for
  // more details.
  // TODO(crbug.com/1150242): Remove this when we have the full fix for the bug.
  if (page_timing_metrics_sender_)
    page_timing_metrics_sender_->SendLatest();
}

void MetricsRenderFrameObserver::ReadyToCommitNavigation(
    blink::WebDocumentLoader* document_loader) {
  // Create a new data use tracker for the new document load.
  provisional_frame_resource_data_use_ =
      std::make_unique<PageResourceDataUse>();
  provisional_frame_resource_id_ = 0;

  // Send current metrics before the next page load commits. Don't reset here
  // as it may be a same document load.
  if (page_timing_metrics_sender_)
    page_timing_metrics_sender_->SendLatest();
}

void MetricsRenderFrameObserver::DidFailProvisionalLoad() {
  // Clear the data use tracker for the provisional navigation that started.
  provisional_frame_resource_data_use_.reset();
}

void MetricsRenderFrameObserver::DidCreateDocumentElement() {
  // If we do not have a render frame or are already tracking this frame, ignore
  // the new document element.
  if (HasNoRenderFrame() || page_timing_metrics_sender_)
    return;

  // We should only track committed navigations for the main frame so ignore new
  // document elements in the main frame.
  if (render_frame()->IsMainFrame())
    return;

  // A new document element was created in a frame that did not commit a
  // provisional load. This can be due to a doc.write in the frame that aborted
  // a navigation. Create a page timing sender to track this load. This sender
  // will only send resource usage updates to the browser process. There
  // currently is not infrastructure in the browser process to monitor this case
  // and properly handle timing updates without a committed load.
  // TODO(https://crbug.com/1097127): Implement proper handling of timing
  // updates in the browser process and create a normal page timing sender.

  // It should not be possible to have a |provisional_frame_resource_data_use_|
  // object at this point. If we did, it means we reached
  // ReadyToCommitNavigation() and aborted prior to load commit which should not
  // be possible.
  DCHECK(!provisional_frame_resource_data_use_);

  Timing timing = GetTiming();
  page_timing_metrics_sender_ = std::make_unique<PageTimingMetricsSender>(
      CreatePageTimingSender(true /* limited_sending_mode */), CreateTimer(),
      std::move(timing.relative_timing), timing.monotonic_timing,
      std::make_unique<PageResourceDataUse>());
  if (ukm_smoothness_data_.IsValid()) {
    page_timing_metrics_sender_->SetUpSmoothnessReporting(
        std::move(ukm_smoothness_data_));
  }
}

void MetricsRenderFrameObserver::DidCommitProvisionalLoad(
    ui::PageTransition transition) {
  // Make sure to release the sender for a previous navigation, if we have one.
  page_timing_metrics_sender_.reset();

  if (HasNoRenderFrame())
    return;

  // Update metadata once the load has been committed. There is no guarantee
  // that the provisional resource will have been reported as an ad by this
  // point. Therefore, need to update metadata for the resource after the load.
  // Consumers may receive the correct ad information late.
  UpdateResourceMetadata(provisional_frame_resource_data_use_->resource_id());

  provisional_frame_resource_id_ =
      provisional_frame_resource_data_use_->resource_id();

  Timing timing = GetTiming();
  page_timing_metrics_sender_ = std::make_unique<PageTimingMetricsSender>(
      CreatePageTimingSender(false /* limited_sending_mode*/), CreateTimer(),
      std::move(timing.relative_timing), timing.monotonic_timing,
      std::move(provisional_frame_resource_data_use_));
  if (ukm_smoothness_data_.IsValid()) {
    page_timing_metrics_sender_->SetUpSmoothnessReporting(
        std::move(ukm_smoothness_data_));
  }
}

void MetricsRenderFrameObserver::SetAdResourceTracker(
    subresource_filter::AdResourceTracker* ad_resource_tracker) {
  // Remove all sources and set a new source for the observer.
  scoped_ad_resource_observation_.Reset();
  scoped_ad_resource_observation_.Observe(ad_resource_tracker);
}

void MetricsRenderFrameObserver::OnAdResourceTrackerGoingAway() {
  DCHECK(scoped_ad_resource_observation_.IsObserving());

  scoped_ad_resource_observation_.Reset();
}

void MetricsRenderFrameObserver::OnAdResourceObserved(int request_id) {
  ad_request_ids_.insert(request_id);
}

void MetricsRenderFrameObserver::OnMainFrameIntersectionChanged(
    const gfx::Rect& main_frame_intersection) {
  if (page_timing_metrics_sender_)
    page_timing_metrics_sender_->OnMainFrameIntersectionChanged(
        main_frame_intersection);
}

void MetricsRenderFrameObserver::OnMobileFriendlinessChanged(
    const blink::MobileFriendliness& mf) {
  if (page_timing_metrics_sender_)
    page_timing_metrics_sender_->DidObserveMobileFriendlinessChanged(mf);
}

bool MetricsRenderFrameObserver::SetUpSmoothnessReporting(
    base::ReadOnlySharedMemoryRegion& shared_memory) {
  if (page_timing_metrics_sender_) {
    page_timing_metrics_sender_->SetUpSmoothnessReporting(
        std::move(shared_memory));
  } else {
    ukm_smoothness_data_ = std::move(shared_memory);
  }
  return true;
}

void MetricsRenderFrameObserver::MaybeSetCompletedBeforeFCP(int request_id) {
  if (HasNoRenderFrame())
    return;

  const blink::WebPerformance& perf =
      render_frame()->GetWebFrame()->Performance();

  // Blink returns 0 if the performance metrics are unavailable. Check that
  // navigation start is set to determine if performance metrics are
  // available.
  if (perf.NavigationStart() == 0)
    return;

  // This should not be possible, but none the less occasionally fails in edge
  // case tests. Since we don't expect this to be valid, throw out this entry.
  // See crbug.com/1027535.
  if (base::Time::Now() < base::Time::FromDoubleT(perf.NavigationStart()))
    return;

  if (perf.FirstContentfulPaint() == 0)
    before_fcp_request_ids_.insert(request_id);
}

MetricsRenderFrameObserver::Timing::Timing(
    mojom::PageLoadTimingPtr relative_timing,
    const PageTimingMetadataRecorder::MonotonicTiming& monotonic_timing)
    : relative_timing(std::move(relative_timing)),
      monotonic_timing(monotonic_timing) {}

MetricsRenderFrameObserver::Timing::~Timing() = default;

MetricsRenderFrameObserver::Timing::Timing(Timing&&) = default;
MetricsRenderFrameObserver::Timing& MetricsRenderFrameObserver::Timing::
operator=(Timing&&) = default;

void MetricsRenderFrameObserver::UpdateResourceMetadata(int request_id) {
  if (!page_timing_metrics_sender_)
    return;

  // If the request is an ad, pop it off the list of known ad requests.
  auto ad_resource_it = ad_request_ids_.find(request_id);
  bool reported_as_ad_resource =
      ad_request_ids_.find(request_id) != ad_request_ids_.end();
  if (reported_as_ad_resource)
    ad_request_ids_.erase(ad_resource_it);

  // If the request completed before fcp, pop it off the list of known
  // before-fcp requests.
  auto before_fcp_it = before_fcp_request_ids_.find(request_id);
  bool completed_before_fcp = before_fcp_it != before_fcp_request_ids_.end();
  if (completed_before_fcp) {
    before_fcp_request_ids_.erase(before_fcp_it);
  }

  bool is_main_frame_resource = render_frame()->IsMainFrame();

  if (provisional_frame_resource_data_use_ &&
      provisional_frame_resource_data_use_->resource_id() == request_id) {
    if (reported_as_ad_resource)
      provisional_frame_resource_data_use_->SetReportedAsAdResource(
          reported_as_ad_resource);
    provisional_frame_resource_data_use_->SetIsMainFrameResource(
        is_main_frame_resource);
    // Don't bother with before-fcp metrics for a provisional frame.
  } else {
    page_timing_metrics_sender_->UpdateResourceMetadata(
        request_id, reported_as_ad_resource, is_main_frame_resource,
        completed_before_fcp);
  }
}

void MetricsRenderFrameObserver::SendMetrics() {
  if (!page_timing_metrics_sender_)
    return;
  if (HasNoRenderFrame())
    return;
  Timing timing = GetTiming();
  page_timing_metrics_sender_->Update(std::move(timing.relative_timing),
                                      timing.monotonic_timing);
}

MetricsRenderFrameObserver::Timing MetricsRenderFrameObserver::GetTiming()
    const {
  const blink::WebPerformance& perf =
      render_frame()->GetWebFrame()->Performance();

  mojom::PageLoadTimingPtr timing(CreatePageLoadTiming());
  PageTimingMetadataRecorder::MonotonicTiming monotonic_timing;
  double start = perf.NavigationStart();
  timing->navigation_start = base::Time::FromDoubleT(start);
  monotonic_timing.navigation_start = perf.NavigationStartAsMonotonicTime();
  if (perf.InputForNavigationStart() > 0.0) {
    timing->input_to_navigation_start =
        ClampDelta(start, perf.InputForNavigationStart());
  }
  if (perf.FirstInputDelay().has_value()) {
    timing->interactive_timing->first_input_delay = *perf.FirstInputDelay();
  }
  if (perf.FirstInputTimestamp().has_value()) {
    timing->interactive_timing->first_input_timestamp =
        ClampDelta((*perf.FirstInputTimestamp()).InSecondsF(), start);
  }
  if (perf.LongestInputDelay().has_value()) {
    timing->interactive_timing->longest_input_delay = *perf.LongestInputDelay();
  }
  if (perf.LongestInputTimestamp().has_value()) {
    timing->interactive_timing->longest_input_timestamp =
        ClampDelta((*perf.LongestInputTimestamp()).InSecondsF(), start);
  }
  if (perf.FirstInputProcessingTime().has_value()) {
    timing->interactive_timing->first_input_processing_time =
        *perf.FirstInputProcessingTime();
  }
  if (perf.FirstScrollDelay().has_value()) {
    timing->interactive_timing->first_scroll_delay = *perf.FirstScrollDelay();
  }
  if (perf.FirstScrollTimestamp().has_value()) {
    timing->interactive_timing->first_scroll_timestamp =
        ClampDelta((*perf.FirstScrollTimestamp()).InSecondsF(), start);
  }
  if (perf.ResponseStart() > 0.0)
    timing->response_start = ClampDelta(perf.ResponseStart(), start);
  if (perf.DomContentLoadedEventStart() > 0.0) {
    timing->document_timing->dom_content_loaded_event_start =
        ClampDelta(perf.DomContentLoadedEventStart(), start);
  }
  if (perf.LoadEventStart() > 0.0) {
    timing->document_timing->load_event_start =
        ClampDelta(perf.LoadEventStart(), start);
  }
  if (perf.FirstPaint() > 0.0)
    timing->paint_timing->first_paint = ClampDelta(perf.FirstPaint(), start);
  if (!perf.BackForwardCacheRestore().empty()) {
    blink::WebPerformance::BackForwardCacheRestoreTimings restore_timings =
        perf.BackForwardCacheRestore();
    for (const auto& restore_timing : restore_timings) {
      double navigation_start = restore_timing.navigation_start;
      double first_paint = restore_timing.first_paint;
      absl::optional<base::TimeDelta> first_input_delay =
          restore_timing.first_input_delay;

      auto back_forward_cache_timing = mojom::BackForwardCacheTiming::New();
      if (first_paint) {
        back_forward_cache_timing
            ->first_paint_after_back_forward_cache_restore =
            ClampDelta(first_paint, navigation_start);
      }
      for (double raf : restore_timing.request_animation_frames) {
        if (!raf)
          break;
        back_forward_cache_timing
            ->request_animation_frames_after_back_forward_cache_restore
            .push_back(ClampDelta(raf, navigation_start));
      }
      if (first_input_delay.has_value()) {
        back_forward_cache_timing
            ->first_input_delay_after_back_forward_cache_restore =
            first_input_delay;
      }
      timing->back_forward_cache_timings.push_back(
          std::move(back_forward_cache_timing));
    }
  }
  if (perf.FirstImagePaint() > 0.0) {
    timing->paint_timing->first_image_paint =
        ClampDelta(perf.FirstImagePaint(), start);
  }
  if (perf.FirstContentfulPaint() > 0.0) {
    DCHECK(perf.FirstEligibleToPaint() > 0);
    timing->paint_timing->first_contentful_paint =
        ClampDelta(perf.FirstContentfulPaint(), start);
    monotonic_timing.first_contentful_paint =
        ClampToStart(perf.FirstContentfulPaintAsMonotonicTime(),
                     perf.NavigationStartAsMonotonicTime());
  }
  if (perf.FirstMeaningfulPaint() > 0.0) {
    timing->paint_timing->first_meaningful_paint =
        ClampDelta(perf.FirstMeaningfulPaint(), start);
  }
  if (perf.LargestImagePaintSize() > 0) {
    timing->paint_timing->largest_contentful_paint->largest_image_paint_size =
        perf.LargestImagePaintSize();
    // Note that size can be nonzero while the time is 0 since a time of 0 is
    // sent when the image is painting. We assign the time even when it is 0 so
    // that it's not ignored, but need to be careful when doing operations on
    // the value.
    timing->paint_timing->largest_contentful_paint->largest_image_paint =
        perf.LargestImagePaint() == 0.0
            ? base::TimeDelta()
            : ClampDelta(perf.LargestImagePaint(), start);
    timing->paint_timing->largest_contentful_paint->type =
        perf.LargestContentfulPaintType();
    timing->paint_timing->largest_contentful_paint->image_bpp =
        perf.LargestContentfulPaintImageBPP();
  }
  if (perf.LargestTextPaintSize() > 0) {
    // LargestTextPaint and LargestTextPaintSize should be available at the
    // same time. This is a renderer side DCHECK to ensure this.
    DCHECK(perf.LargestTextPaint());
    timing->paint_timing->largest_contentful_paint->largest_text_paint =
        ClampDelta(perf.LargestTextPaint(), start);
    timing->paint_timing->largest_contentful_paint->largest_text_paint_size =
        perf.LargestTextPaintSize();
  }
  if (perf.ExperimentalLargestImagePaintSize() > 0) {
    timing->paint_timing->experimental_largest_contentful_paint
        ->largest_image_paint_size = perf.ExperimentalLargestImagePaintSize();
    // Note that size can be nonzero while the time is 0 since a time of 0 is
    // sent when the image is painting. We assign the time even when it is 0 so
    // that it's not ignored, but need to be careful when doing operations on
    // the value.
    timing->paint_timing->experimental_largest_contentful_paint
        ->largest_image_paint =
        perf.ExperimentalLargestImagePaint() == 0.0
            ? base::TimeDelta()
            : ClampDelta(perf.ExperimentalLargestImagePaint(), start);
    timing->paint_timing->experimental_largest_contentful_paint->type =
        perf.LargestContentfulPaintType();
  }
  if (perf.ExperimentalLargestTextPaintSize() > 0) {
    // ExperimentalLargestTextPaint and ExperimentalLargestTextPaintSize should
    // be available at the same time. This is a renderer side DCHECK to ensure
    // this.
    DCHECK(perf.ExperimentalLargestTextPaint());
    timing->paint_timing->experimental_largest_contentful_paint
        ->largest_text_paint =
        ClampDelta(perf.ExperimentalLargestTextPaint(), start);
    timing->paint_timing->experimental_largest_contentful_paint
        ->largest_text_paint_size = perf.ExperimentalLargestTextPaintSize();
  }
  // It is possible for a frame to switch from eligible for painting to
  // ineligible for it prior to the first paint. If this occurs, we need to
  // propagate the null value.
  if (perf.FirstEligibleToPaint() > 0) {
    timing->paint_timing->first_eligible_to_paint =
        ClampDelta(perf.FirstEligibleToPaint(), start);
  } else {
    timing->paint_timing->first_eligible_to_paint.reset();
  }
  if (perf.FirstInputOrScrollNotifiedTimestamp() > 0) {
    timing->paint_timing->first_input_or_scroll_notified_timestamp =
        ClampDelta(perf.FirstInputOrScrollNotifiedTimestamp(), start);
  }
  if (perf.ParseStart() > 0.0)
    timing->parse_timing->parse_start = ClampDelta(perf.ParseStart(), start);
  if (perf.ParseStop() > 0.0)
    timing->parse_timing->parse_stop = ClampDelta(perf.ParseStop(), start);
  if (timing->parse_timing->parse_start) {
    // If we started parsing, record all parser durations such as the amount of
    // time blocked on script load, even if those values are zero.
    timing->parse_timing->parse_blocked_on_script_load_duration =
        base::Seconds(perf.ParseBlockedOnScriptLoadDuration());
    timing->parse_timing
        ->parse_blocked_on_script_load_from_document_write_duration =
        base::Seconds(perf.ParseBlockedOnScriptLoadFromDocumentWriteDuration());
    timing->parse_timing->parse_blocked_on_script_execution_duration =
        base::Seconds(perf.ParseBlockedOnScriptExecutionDuration());
    timing->parse_timing
        ->parse_blocked_on_script_execution_from_document_write_duration =
        base::Seconds(
            perf.ParseBlockedOnScriptExecutionFromDocumentWriteDuration());
  }
  if (perf.LastPortalActivatedPaint().has_value()) {
    timing->paint_timing->portal_activated_paint =
        *perf.LastPortalActivatedPaint();
  }
  if (perf.PrerenderActivationStart().has_value())
    timing->activation_start = perf.PrerenderActivationStart();

  if (perf.UserTimingMarkFullyLoaded().has_value())
    timing->user_timing_mark_fully_loaded = perf.UserTimingMarkFullyLoaded();

  if (perf.UserTimingMarkFullyVisible().has_value())
    timing->user_timing_mark_fully_visible = perf.UserTimingMarkFullyVisible();

  if (perf.UserTimingMarkInteractive().has_value())
    timing->user_timing_mark_interactive = perf.UserTimingMarkInteractive();

  return Timing(std::move(timing), monotonic_timing);
}

std::unique_ptr<base::OneShotTimer> MetricsRenderFrameObserver::CreateTimer() {
  return std::make_unique<base::OneShotTimer>();
}

std::unique_ptr<PageTimingSender>
MetricsRenderFrameObserver::CreatePageTimingSender(bool limited_sending_mode) {
  return base::WrapUnique<PageTimingSender>(
      new MojoPageTimingSender(render_frame(), limited_sending_mode));
}

bool MetricsRenderFrameObserver::HasNoRenderFrame() const {
  bool no_frame = !render_frame() || !render_frame()->GetWebFrame();
  DCHECK(!no_frame);
  return no_frame;
}

void MetricsRenderFrameObserver::OnDestruct() {
  delete this;
}

}  // namespace page_load_metrics
