File: startup_metric_utils.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (196 lines) | stat: -rw-r--r-- 8,663 bytes parent folder | download | duplicates (4)
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
// Copyright 2023 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_STARTUP_METRIC_UTILS_BROWSER_STARTUP_METRIC_UTILS_H_
#define COMPONENTS_STARTUP_METRIC_UTILS_BROWSER_STARTUP_METRIC_UTILS_H_

#include <optional>

#include "base/component_export.h"
#include "base/time/time.h"
#include "components/startup_metric_utils/common/startup_metric_utils.h"

// Utility functions to support metric collection for browser-process-specific
// startup. Timings should use TimeTicks whenever possible.

namespace startup_metric_utils {

// Result of an attempt to create the first run sentinel file.
//
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class FirstRunSentinelCreationResult {
  // The sentinel file was created without error.
  kSuccess = 0,
  // Obtaining the path to the sentinel file failed. Might indicate issues
  // in determining the user data dir.
  kFailedToGetPath = 1,
  // The sentinel file already exists. Can indicate that a switch to override
  // the first run state was used.
  kFilePathExists = 2,
  // File system error, writing the file failed.
  kFileSystemError = 3,
  kMaxValue = kFileSystemError,
};

class COMPONENT_EXPORT(STARTUP_METRIC_UTILS)
    BrowserStartupMetricRecorder final {
 public:
  // Clears variables which would be set multiple times in the case of tests
  // being run multiple times in the same process.
  void ResetSessionForTesting();

  // Returns true when browser UI was not launched normally: some other UI was
  // shown first or browser was launched in background mode.
  bool WasMainWindowStartupInterrupted() const;

  // Call this when displaying UI that might potentially delay startup events.
  //
  // Note on usage: This function is idempotent and its overhead is low enough
  // in comparison with UI display that it's OK to call it on every
  // UI invocation regardless of whether the browser window has already
  // been displayed or not.
  void SetNonBrowserUIDisplayed();

  // Call this when background mode gets enabled, as it might delay startup
  // events.
  void SetBackgroundModeEnabled();

  // Call this with the time recorded just before the message loop is started.
  // Must be called after RecordApplicationStartTime(), because it computes time
  // deltas based on application start time.
  // |is_first_run| - is the current launch part of a first run.
  void RecordBrowserMainMessageLoopStart(base::TimeTicks ticks,
                                         bool is_first_run);

  // Call this with the time recorded just after the message loop first reaches
  // idle. Must be called after RecordApplicationStartTime(), because it
  // computes time deltas based on application start time.
  void RecordBrowserMainLoopFirstIdle(base::TimeTicks ticks);

  // Call this with the time when the first browser window became visible.
  void RecordBrowserWindowDisplay(base::TimeTicks ticks);

  // Call this with the time when the browser window paints its children for the
  // first time.
  void RecordBrowserWindowFirstPaintTicks(base::TimeTicks ticks);

  // Call this with the time when the Privacy Sandbox Attestations component
  // becomes ready for the first time.
  void RecordPrivacySandboxAttestationsFirstReady(base::TimeTicks ticks);

  // Call this with the time when a Privacy Sandbox API attestation is checked
  // for the first time.
  void RecordPrivacySandboxAttestationFirstCheck(base::TimeTicks ticks);

  // Call this with the time when the first web contents had a non-empty paint,
  // only if the first web contents was unimpeded in its attempt to do so. Must
  // be called after RecordApplicationStartTime(), because it computes time
  // deltas based on application start time.
  void RecordFirstWebContentsNonEmptyPaint(
      base::TimeTicks now,
      base::TimeTicks render_process_host_init_time);

  // Call this with the time when the first web contents began navigating its
  // main frame / successfully committed its navigation for the main frame.
  // These functions must be called after RecordApplicationStartTime(), because
  // they compute time deltas based on application start time.
  void RecordFirstWebContentsMainNavigationStart(base::TimeTicks ticks);
  void RecordFirstWebContentsMainNavigationFinished(base::TimeTicks ticks);

  // Call this with the time when the Browser window painted its children for
  // the first time. Must be called after RecordApplicationStartTime(), because
  // it computes time deltas based on application start time.
  void RecordBrowserWindowFirstPaint(base::TimeTicks ticks);

  void RecordFirstRunSentinelCreation(FirstRunSentinelCreationResult result);

  // On Windows, records the number of hard-faults that have occurred in the
  // current chrome.exe process since it was started. This is a nop on other
  // platforms.
  void RecordHardFaultHistogram();

  // Call this to record an arbitrary startup timing histogram with startup
  // temperature and a trace event. Records the time between
  // `completion_ticks` and the application start. See the
  // `StartupTemperature` enum for definition of the startup temperature. A
  // metric logged using this function must have an affected-histogram entry
  // in the definition of the StartupTemperature suffix in histograms.xml. Set
  // `set_non_browser_ui_displayed` to true if the recorded event blocks the
  // browser UI on user input. In this case any future startup histogram
  // timing would be skewed and will not be recorded. This function must be
  // called after RecordApplicationStartTime(), because it computes time
  // deltas based on application start time. `histogram_name` must point to a
  // statically allocated string (such as a string literal) since the pointer
  // will be stored for an indefinite amount of time before being written to a
  // trace (see the "Memory scoping note" in
  // base/trace_event/common/trace_event_common.h.)
  void RecordExternalStartupMetric(const char* histogram_name,
                                   base::TimeTicks completion_ticks,
                                   bool set_non_browser_ui_displayed);

  bool ShouldLogStartupHistogram() const;

#if BUILDFLAG(IS_CHROMEOS)
  // On ChromeOS, the time at which the first browser window is opened may not
  // match the application start time mainly because the login screen is often
  // shown first and the user must log in before a browser window can be opened.
  // ChromeOS code can call this if it knows a browser window is being opened to
  // mark the start time for all `Startup.FirstWebContents.*` metrics. This is
  // a no-op if a start time has already been recorded.
  //
  // For all other platforms, `application_start_ticks_` is used for
  // `Startup.FirstWebContents.*` metrics.
  void RecordWebContentsStartTime(base::TimeTicks ticks);
#endif  // BUILDFLAG(IS_CHROMEOS)

 private:
  // Returns the globally unique `BrowserStartupMetricRecorder`.
  friend COMPONENT_EXPORT(STARTUP_METRIC_UTILS)
      BrowserStartupMetricRecorder& GetBrowser();

  // Only permit construction from within GetBrowser().
  BrowserStartupMetricRecorder() = default;

#if BUILDFLAG(IS_WIN)
  // Returns the hard fault count of the current process, or nullopt if it can't
  // be determined.
  std::optional<uint32_t> GetHardFaultCountForCurrentProcess();
#endif

  void RecordMessageLoopStartTicks(base::TimeTicks ticks);

  base::TimeTicks GetWebContentsStartTicks() const;

  void EmitHistogramWithTemperatureAndTraceEvent(
      void (*histogram_function)(std::string_view name, base::TimeDelta),
      const char* histogram_basename,
      base::TimeTicks begin_ticks,
      base::TimeTicks end_ticks);

  // Mark as volatile to defensively make sure usage is thread-safe.
  // Note that at the time of this writing, access is only on the UI thread.
  volatile bool main_window_startup_interrupted_ = false;

  base::TimeTicks message_loop_start_ticks_;

  base::TimeTicks browser_window_display_ticks_;

  base::TimeTicks browser_window_first_paint_ticks_;

  // May be null, in which case, fall back to
  // `CommonStartupMetricRecorder.application_start_ticks_`.
  base::TimeTicks web_contents_start_ticks_;

  bool is_privacy_sandbox_attestations_component_ready_recorded_ = false;

  bool is_privacy_sandbox_attestations_first_check_recorded_ = false;
};

COMPONENT_EXPORT(STARTUP_METRIC_UTILS)
BrowserStartupMetricRecorder& GetBrowser();

}  // namespace startup_metric_utils

#endif  // COMPONENTS_STARTUP_METRIC_UTILS_BROWSER_STARTUP_METRIC_UTILS_H_