File: metrics_render_frame_observer.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (200 lines) | stat: -rw-r--r-- 8,762 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_PAGE_LOAD_METRICS_RENDERER_METRICS_RENDER_FRAME_OBSERVER_H_
#define COMPONENTS_PAGE_LOAD_METRICS_RENDERER_METRICS_RENDER_FRAME_OBSERVER_H_

#include <memory>
#include <optional>
#include <set>

#include "base/scoped_observation.h"
#include "components/page_load_metrics/common/page_load_timing.h"
#include "components/page_load_metrics/renderer/page_resource_data_use.h"
#include "components/page_load_metrics/renderer/page_timing_metadata_recorder.h"
#include "content/public/renderer/render_frame_observer.h"
#include "third_party/blink/public/common/loader/loading_behavior_flag.h"
#include "third_party/blink/public/common/subresource_load_metrics.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
#include "third_party/blink/public/web/web_local_frame_observer.h"

class GURL;

namespace base {
class OneShotTimer;
}  // namespace base

namespace blink {
struct JavaScriptFrameworkDetectionResult;
struct SoftNavigationMetrics;
}  // namespace blink

namespace page_load_metrics {

namespace internal {
const char kPageLoadInternalSoftNavigationFromStartInvalidTiming[] =
    "PageLoad.Internal.SoftNavigationFromStartInvalidTiming";

// These values are recorded into a UMA histogram as scenarios where the start
// time of soft navigation ends up being 0. These entries
// should not be renumbered and the numeric values should not be reused. These
// entries should be kept in sync with the definition in
// tools/metrics/histograms/enums.xml
// TODO(crbug.com/40074158): Remove the code here and related code once the bug
// is resolved.
enum class SoftNavigationFromStartInvalidTimingReasons {
  kSoftNavStartTimeIsZeroAndLtNavStart = 0,
  kSoftNavStartTimeIsZeroAndEqNavStart = 1,
  kSoftNavStartTimeIsNonZeroAndEqNavStart = 2,
  kSoftNavStartTimeIsNonZeroAndLtNavStart = 3,
  kMaxValue = kSoftNavStartTimeIsNonZeroAndLtNavStart,
};

void RecordUmaForkPageLoadInternalSoftNavigationFromStartInvalidTiming(
    base::TimeDelta start_time_relative_to_reference,
    double nav_start_to_reference);

}  // namespace internal

class PageTimingMetricsSender;
class PageTimingSender;

// MetricsRenderFrameObserver observes RenderFrame notifications, and sends page
// load timing information to the browser process over IPC. A
// MetricsRenderFrameObserver is instantiated for each frame (main frames and
// child frames). MetricsRenderFrameObserver dispatches timing and metadata
// updates for main frames, but only metadata updates for child frames.
class MetricsRenderFrameObserver : public content::RenderFrameObserver,
                                   public blink::WebLocalFrameObserver {
 public:
  explicit MetricsRenderFrameObserver(content::RenderFrame* render_frame);

  MetricsRenderFrameObserver(const MetricsRenderFrameObserver&) = delete;
  MetricsRenderFrameObserver& operator=(const MetricsRenderFrameObserver&) =
      delete;

  ~MetricsRenderFrameObserver() override;

  // RenderFrameObserver implementation
  void DidChangePerformanceTiming() override;
  void DidObserveUserInteraction(base::TimeTicks max_event_start,
                                 base::TimeTicks max_event_queued_main_thread,
                                 base::TimeTicks max_event_commit_finish,
                                 base::TimeTicks max_event_end,
                                 uint64_t interaction_offset) override;
  void DidChangeCpuTiming(base::TimeDelta time) override;
  void DidObserveLoadingBehavior(blink::LoadingBehaviorFlag behavior) override;
  void DidObserveJavaScriptFrameworks(
      const blink::JavaScriptFrameworkDetectionResult&) override;
  void DidObserveSubresourceLoad(
      const blink::SubresourceLoadMetrics& subresource_load_metrics) override;
  void DidObserveNewFeatureUsage(
      const blink::UseCounterFeature& feature) override;
  void DidObserveSoftNavigation(blink::SoftNavigationMetrics metrics) override;
  void DidObserveLayoutShift(double score, bool after_input_or_scroll) override;
  void DidStartResponse(const url::SchemeHostPort& final_response_url,
                        int request_id,
                        const network::mojom::URLResponseHead& response_head,
                        network::mojom::RequestDestination request_destination,
                        bool is_ad_resource) override;
  void DidReceiveTransferSizeUpdate(int request_id,
                                    int received_data_length) override;
  void DidCompleteResponse(
      int request_id,
      const network::URLLoaderCompletionStatus& status) override;
  void DidCancelResponse(int request_id) override;
  void DidLoadResourceFromMemoryCache(const GURL& response_url,
                                      int request_id,
                                      int64_t encoded_body_length,
                                      const std::string& mime_type,
                                      bool from_archive) override;
  void DidStartNavigation(
      const GURL& url,
      std::optional<blink::WebNavigationType> navigation_type) override;
  void DidSetPageLifecycleState(bool restoring_from_bfcache) override;

  void ReadyToCommitNavigation(
      blink::WebDocumentLoader* document_loader) override;
  void DidFailProvisionalLoad() override;
  void DidCommitProvisionalLoad(ui::PageTransition transition) override;
  void DidCreateDocumentElement() override;
  void OnDestruct() override;

  // Invoked when a frame is going away. This is our last chance to send IPCs
  // before being destroyed.
  void WillDetach(blink::DetachReason detach_reason) override;

  void OnMainFrameIntersectionChanged(
      const gfx::Rect& main_frame_intersection_rect) override;
  void OnMainFrameViewportRectangleChanged(
      const gfx::Rect& main_frame_viewport_rect) override;
  void OnMainFrameImageAdRectangleChanged(
      int element_id,
      const gfx::Rect& image_ad_rect) override;

  // blink::WebLocalFrameObserver implementation
  void OnFrameDetached() override;

  bool SetUpUkmReporting(
      base::ReadOnlySharedMemoryRegion& shared_memory_smoothness,
      base::ReadOnlySharedMemoryRegion& shared_memory_dropped_frames) override;

 protected:
  // The relative and monotonic page load timings.
  struct Timing {
    Timing(mojom::PageLoadTimingPtr relative_timing,
           const PageTimingMetadataRecorder::MonotonicTiming& monotonic_timing);
    ~Timing();

    Timing(const Timing&) = delete;
    Timing& operator=(const Timing&) = delete;
    Timing(Timing&&);
    Timing& operator=(Timing&&);

    mojom::PageLoadTimingPtr relative_timing;
    PageTimingMetadataRecorder::MonotonicTiming monotonic_timing;
  };

 private:
  // Updates the metadata for the page resource associated with the given
  // request_id. Removes the request_id from the list of known ads if it is an
  // ad.
  void UpdateResourceMetadata(int request_id);

  void SendMetrics();
  void OnMetricsSenderCreated();
  virtual Timing GetTiming() const;
  virtual mojom::SoftNavigationMetricsPtr GetSoftNavigationMetrics() const;
  virtual mojom::CustomUserTimingMarkPtr GetCustomUserTimingMark() const;
  virtual std::unique_ptr<base::OneShotTimer> CreateTimer();
  virtual std::unique_ptr<PageTimingSender> CreatePageTimingSender(
      bool limited_sending_mode);
  virtual bool HasNoRenderFrame() const;
  virtual bool IsMainFrame() const;

  // Collects the data use of the frame request for a provisional load until the
  // load is committed. We want to collect data use for completed navigations in
  // this class, but the various navigation callbacks do not provide enough data
  // for us to use them for data attribution. Instead, we try to get this
  // information from ongoing resource requests on the previous page (or right
  // before this page loads in a new renderer).
  std::unique_ptr<PageResourceDataUse> provisional_frame_resource_data_use_;

  // Handle to the shared memory for transporting smoothness related ukm data.
  base::ReadOnlySharedMemoryRegion ukm_smoothness_data_;
  base::ReadOnlySharedMemoryRegion ukm_dropped_frames_data_;

  // The main frame intersection rectangle signal received before
  // `page_timing_metrics_sender_` is created. The signal will be send out right
  // after `page_timing_metrics_sender_` is created.
  std::optional<gfx::Rect>
      main_frame_intersection_rect_before_metrics_sender_created_;

  // Will be null when we're not actively sending metrics.
  std::unique_ptr<PageTimingMetricsSender> page_timing_metrics_sender_;
};

}  // namespace page_load_metrics

#endif  // COMPONENTS_PAGE_LOAD_METRICS_RENDERER_METRICS_RENDER_FRAME_OBSERVER_H_