blob: 1e8d6447b456420dfc83f5fda62ca2476bb3de78 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2020 The Chromium Authors
Alexander Timinfc9756782020-12-23 22:05:522// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_TRACING_STARTUP_TRACING_CONTROLLER_H_
6#define CONTENT_BROWSER_TRACING_STARTUP_TRACING_CONTROLLER_H_
7
Lei Zhang0d85a9d32021-05-06 19:21:478#include "base/files/file_path.h"
Alexander Timinfc9756782020-12-23 22:05:529#include "base/threading/sequence_bound.h"
Alexander Timin2149a9312021-01-08 10:03:5710#include "content/common/content_export.h"
Alexander Timinfc9756782020-12-23 22:05:5211
12namespace content {
13
14// Class responsible for starting and stopping startup tracing as configured by
15// StartupTracingConfig. All interactions with it are limited to UI thread, but
16// the actual logic lives on a background ThreadPool sequence.
Alexander Timin2149a9312021-01-08 10:03:5717class CONTENT_EXPORT StartupTracingController {
Alexander Timinfc9756782020-12-23 22:05:5218 public:
19 StartupTracingController();
20 ~StartupTracingController();
21
22 static StartupTracingController& GetInstance();
23
Alexander Timina3a86682021-01-08 12:26:0624 // Stop the trace recording, write the trace to disk and block until complete.
25 // Intended to be used in the situation when the browser process is going to
26 // crash (e.g. DCHECK failure) and we want to avoid losing the trace data. Can
27 // be called from any thread.
28 // May not succeed if called from a sequence that is required to be responsive
29 // during trace finalisation.
30 static void EmergencyStop();
31
Alexander Timinfc9756782020-12-23 22:05:5232 void StartIfNeeded();
33 void WaitUntilStopped();
ssid6bedaa92021-06-16 10:25:2434 void ShutdownAndWaitForStopIfNeeded();
Alexander Timinfc9756782020-12-23 22:05:5235
Alexander Timin2149a9312021-01-08 10:03:5736 // By default, a trace is written into a temporary file which then is renamed,
37 // however this can lead to data loss when the browser process crashes.
38 // Embedders can disable this (especially if a name provided to
39 // SetDefaultBasename makes it clear that the trace is incomplete and final
40 // name will be provided via SetDefaultBasename call before calling Stop).
41 enum class TempFilePolicy {
42 kUseTemporaryFile,
43 kWriteDirectly,
44 };
45 void SetUsingTemporaryFile(TempFilePolicy temp_file_policy);
46
47 // Set default basename for the trace output file to allow //content embedders
48 // to customise it using some metadata (like test names).
49 //
50 // If --enable-trace-output is a directory (default value, empty, designated
51 // "current directory"), then the startup trace will be written in a file with
52 // the given basename in this directory. Depending on the |extension_type|,
53 // an appropriate extension (.json or .proto) will be added.
54 //
55 // Note that embedders can call it even after tracing has started and Perfetto
56 // started streaming the trace into it — in that case,
57 // StartupTracingController will rename the file after finishing. However,
58 // this is guaranteed to work only when tracing lasts until Stop() (not with
59 // duration-based tracing).
60 enum class ExtensionType {
61 kAppendAppropriate,
62 kNone,
63 };
64 void SetDefaultBasename(std::string basename, ExtensionType extension_type);
65 // As the test harness calls SetDefaultBasename, expose ForTest() version for
66 // the tests checking the StartupTracingController logic itself.
67 void SetDefaultBasenameForTest(std::string basename,
68 ExtensionType extension_type);
69
70 bool is_finished_for_testing() const { return state_ == State::kStopped; }
71
ssid6bedaa92021-06-16 10:25:2472 void set_continue_on_shutdown_for_testing() {
73 should_continue_on_shutdown_ = true;
74 }
75
Alexander Timinfc9756782020-12-23 22:05:5276 private:
77 void Stop(base::OnceClosure on_finished_callback);
78
79 void OnStoppedOnUIThread();
80
Alexander Timin2149a9312021-01-08 10:03:5781 base::FilePath GetOutputPath();
82
Alexander Timinfc9756782020-12-23 22:05:5283 enum class State {
Alexander Timin2149a9312021-01-08 10:03:5784 kNotEnabled,
Alexander Timinfc9756782020-12-23 22:05:5285 kRunning,
Alexander Timin2149a9312021-01-08 10:03:5786 kStopped,
Alexander Timinfc9756782020-12-23 22:05:5287 };
Alexander Timin2149a9312021-01-08 10:03:5788 State state_ = State::kNotEnabled;
Alexander Timinfc9756782020-12-23 22:05:5289
90 // All actual interactions with the tracing service and the process of writing
91 // files happens on a background thread.
92 class BackgroundTracer;
93 base::SequenceBound<BackgroundTracer> background_tracer_;
94
95 base::OnceClosure on_tracing_finished_;
96 base::FilePath output_file_;
Alexander Timin2149a9312021-01-08 10:03:5797
98 std::string default_basename_;
99 bool basename_for_test_set_ = false;
ssid6bedaa92021-06-16 10:25:24100 // Used for testing only
101 bool should_continue_on_shutdown_ = false;
Alexander Timin2149a9312021-01-08 10:03:57102
Sunny Sachanandanibfd462f52025-08-08 21:31:34103 // Write directly to trace file on iOS since there might not be a graceful
104 // shutdown for tracing to stop with continuous background tracing.
105 TempFilePolicy temp_file_policy_ =
106#if BUILDFLAG(IS_IOS)
107 TempFilePolicy::kWriteDirectly;
108#else
109 TempFilePolicy::kUseTemporaryFile;
110#endif
Alexander Timinfc9756782020-12-23 22:05:52111};
112
113} // namespace content
114
115#endif // CONTENT_BROWSER_TRACING_STARTUP_TRACING_CONTROLLER_H_