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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
content / browser / tracing / background_tracing_manager_impl.h [blame]
// 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 CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_MANAGER_IMPL_H_
#define CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_MANAGER_IMPL_H_
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/no_destructor.h"
#include "base/observer_list.h"
#include "base/threading/sequence_bound.h"
#include "base/timer/timer.h"
#include "base/token.h"
#include "base/trace_event/named_trigger.h"
#include "content/browser/tracing/background_tracing_config_impl.h"
#include "content/browser/tracing/trace_report/trace_report.mojom.h"
#include "content/browser/tracing/trace_report/trace_report_database.h"
#include "content/browser/tracing/trace_report/trace_upload_list.h"
#include "content/browser/tracing/tracing_scenario.h"
#include "content/common/content_export.h"
#include "content/public/browser/background_tracing_manager.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/tracing/public/cpp/perfetto/trace_event_data_source.h"
#include "services/tracing/public/mojom/background_tracing_agent.mojom.h"
namespace tracing::mojom {
class BackgroundTracingAgent;
class BackgroundTracingAgentProvider;
} // namespace tracing::mojom
namespace content {
namespace mojom {
class ChildProcess;
} // namespace mojom
class BackgroundTracingActiveScenario;
class TracingDelegate;
CONTENT_EXPORT BASE_DECLARE_FEATURE(kBackgroundTracingDatabase);
class BackgroundTracingManagerImpl
: public BackgroundTracingManager,
public base::trace_event::NamedTriggerManager,
public TraceUploadList,
public TracingScenario::Delegate {
public:
class AgentObserver {
public:
virtual void OnAgentAdded(
tracing::mojom::BackgroundTracingAgent* agent) = 0;
virtual void OnAgentRemoved(
tracing::mojom::BackgroundTracingAgent* agent) = 0;
};
// Delegate to store and read application preferences for startup tracing, to
// isolate the feature for testing.
class PreferenceManager {
public:
virtual bool GetBackgroundStartupTracingEnabled() const = 0;
virtual ~PreferenceManager() = default;
};
using ScenarioCountMap = base::flat_map<std::string, size_t>;
using FinishedProcessingCallback =
TraceUploadList::FinishedProcessingCallback;
// These values are used for a histogram. Do not reorder.
enum class Metrics {
SCENARIO_ACTIVATION_REQUESTED = 0,
SCENARIO_ACTIVATED_SUCCESSFULLY = 1,
RECORDING_ENABLED = 2,
PREEMPTIVE_TRIGGERED = 3,
REACTIVE_TRIGGERED = 4,
FINALIZATION_ALLOWED = 5,
FINALIZATION_DISALLOWED = 6,
FINALIZATION_STARTED = 7,
OBSOLETE_FINALIZATION_COMPLETE = 8,
SCENARIO_ACTION_FAILED_LOWRES_CLOCK = 9,
UPLOAD_FAILED = 10,
UPLOAD_SUCCEEDED = 11,
STARTUP_SCENARIO_TRIGGERED = 12,
LARGE_UPLOAD_WAITING_TO_RETRY = 13,
SYSTEM_TRIGGERED = 14,
REACHED_CODE_SCENARIO_TRIGGERED = 15,
FINALIZATION_STARTED_WITH_LOCAL_OUTPUT = 16,
DATABASE_INITIALIZATION_FAILED = 17,
DATABASE_CLEANUP_FAILED = 18,
SAVE_TRACE_FAILED = 19,
SAVE_TRACE_SUCCEEDED = 20,
NUMBER_OF_BACKGROUND_TRACING_METRICS,
};
static void RecordMetric(Metrics metric);
CONTENT_EXPORT static BackgroundTracingManagerImpl& GetInstance();
CONTENT_EXPORT BackgroundTracingManagerImpl();
~BackgroundTracingManagerImpl() override;
BackgroundTracingManagerImpl(const BackgroundTracingManagerImpl&) = delete;
BackgroundTracingManagerImpl& operator=(const BackgroundTracingManagerImpl&) =
delete;
// Callable from any thread.
static void ActivateForProcess(int child_process_id,
mojom::ChildProcess* child_process);
void SetReceiveCallback(ReceiveCallback receive_callback) override;
bool InitializePerfettoTriggerRules(
const perfetto::protos::gen::TracingTriggerRulesConfig& config) override;
bool InitializeFieldScenarios(
const perfetto::protos::gen::ChromeFieldTracingConfig& config,
DataFiltering data_filtering,
bool force_upload,
size_t upload_limit_kb) override;
std::vector<std::string> AddPresetScenarios(
const perfetto::protos::gen::ChromeFieldTracingConfig& config,
DataFiltering data_filtering) override;
bool SetEnabledScenarios(
std::vector<std::string> enabled_scenarios_hashes) override;
bool SetActiveScenario(std::unique_ptr<BackgroundTracingConfig>,
DataFiltering data_filtering) override;
bool HasActiveScenario() override;
void DeleteTracesInDateRange(base::Time start, base::Time end) override;
// TracingScenario::Delegate:
bool OnScenarioActive(TracingScenario* scenario) override;
bool OnScenarioIdle(TracingScenario* scenario) override;
void OnScenarioRecording(TracingScenario* scenario) override;
void SaveTrace(TracingScenario* scenario,
base::Token trace_uuid,
const BackgroundTracingRule* triggered_rule,
std::string&& serialized_trace) override;
void AddNamedTriggerObserver(const std::string& trigger_name,
BackgroundTracingRule* observer);
void RemoveNamedTriggerObserver(const std::string& trigger_name,
BackgroundTracingRule* observer);
// Returns the list of preset scenario hashes and names that were saved,
// whether or not enabled.
CONTENT_EXPORT std::vector<trace_report::mojom::ScenarioPtr>
GetAllFieldScenarios() const;
// Returns the list of field scenario hashes and names that were saved,
// whether or not enabled.
CONTENT_EXPORT std::vector<trace_report::mojom::ScenarioPtr>
GetAllPresetScenarios() const;
// Returns the list of scenario hashes that are currently enabled. These are
// either all preset scenarios or all field scenarios.
CONTENT_EXPORT std::vector<std::string> GetEnabledScenarios() const;
bool HasTraceToUpload() override;
void GetTraceToUpload(
base::OnceCallback<void(std::optional<std::string>,
std::optional<std::string>)>) override;
std::unique_ptr<BackgroundTracingConfig> GetBackgroundTracingConfig(
const std::string& trial_name) override;
void SetSystemProfileRecorder(
base::RepeatingCallback<std::string()> recorder) override;
CONTENT_EXPORT size_t GetScenarioSavedCount(const std::string& scenario_name);
CONTENT_EXPORT void InitializeTraceReportDatabase(
bool open_in_memory = false);
// TraceUploadList
void OpenDatabaseIfExists() override;
void GetAllTraceReports(GetReportsCallback callback) override;
void DeleteSingleTrace(const base::Token& trace_uuid,
FinishedProcessingCallback callback) override;
void DeleteAllTraces(FinishedProcessingCallback callback) override;
void UserUploadSingleTrace(const base::Token& trace_uuid,
FinishedProcessingCallback callback) override;
void DownloadTrace(const base::Token& trace_uuid,
GetProtoCallback callback) override;
// Add/remove EnabledStateTestObserver.
CONTENT_EXPORT void AddEnabledStateObserverForTesting(
BackgroundTracingManager::EnabledStateTestObserver* observer);
CONTENT_EXPORT void RemoveEnabledStateObserverForTesting(
BackgroundTracingManager::EnabledStateTestObserver* observer);
// Add/remove Agent{Observer}.
void AddAgent(tracing::mojom::BackgroundTracingAgent* agent);
void RemoveAgent(tracing::mojom::BackgroundTracingAgent* agent);
void AddAgentObserver(AgentObserver* observer);
void RemoveAgentObserver(AgentObserver* observer);
void AddMetadataGeneratorFunction();
// Called by BackgroundTracingActiveScenario
void OnStartTracingDone();
void OnProtoDataComplete(std::string&& serialized_trace,
const std::string& scenario_name,
const std::string& rule_name,
bool privacy_filter_enabled,
bool force_upload,
const base::Token& uuid);
// For tests
CONTENT_EXPORT BackgroundTracingActiveScenario* GetActiveScenarioForTesting();
CONTENT_EXPORT void InvalidateTriggersCallbackForTesting();
CONTENT_EXPORT bool IsTracingForTesting();
CONTENT_EXPORT void AbortScenarioForTesting() override;
CONTENT_EXPORT void SaveTraceForTesting(std::string&& serialized_trace,
const std::string& scenario_name,
const std::string& rule_name,
const base::Token& uuid) override;
CONTENT_EXPORT void SetPreferenceManagerForTesting(
std::unique_ptr<PreferenceManager> preferences);
private:
#if BUILDFLAG(IS_ANDROID)
// ~1MB compressed size.
constexpr static int kDefaultUploadLimitKb = 5 * 1024;
#else
// Less than 10MB compressed size.
constexpr static int kDefaultUploadLimitKb = 30 * 1024;
#endif
bool RequestActivateScenario();
// Named triggers
bool DoEmitNamedTrigger(const std::string& trigger_name,
std::optional<int32_t>) override;
void GenerateMetadataProto(
perfetto::protos::pbzero::ChromeMetadataPacket* metadata,
bool privacy_filtering_enabled);
void OnScenarioAborted();
static void AddPendingAgent(
int child_process_id,
mojo::PendingRemote<tracing::mojom::BackgroundTracingAgentProvider>
provider);
static void ClearPendingAgent(int child_process_id);
void MaybeConstructPendingAgents();
void OnFinalizeComplete(std::optional<BaseTraceReport> trace_to_upload,
bool success);
void OnTraceDatabaseCreated(ScenarioCountMap scenario_saved_counts,
std::optional<BaseTraceReport> trace_to_upload,
bool success);
void OnTraceDatabaseUpdated(ScenarioCountMap scenario_saved_counts);
void OnTraceSaved(const std::string& scenario_name,
std::optional<NewTraceReport> trace_to_upload,
bool success);
void CleanDatabase();
size_t GetTraceUploadLimitKb() const;
std::unique_ptr<TracingDelegate> delegate_;
std::unique_ptr<BackgroundTracingActiveScenario> legacy_active_scenario_;
std::vector<std::unique_ptr<TracingScenario>> field_scenarios_;
base::flat_map<std::string, std::unique_ptr<TracingScenario>>
preset_scenarios_;
std::vector<raw_ptr<TracingScenario>> enabled_scenarios_;
raw_ptr<TracingScenario> active_scenario_{nullptr};
std::vector<std::unique_ptr<BackgroundTracingRule>> trigger_rules_;
ReceiveCallback receive_callback_;
base::RepeatingCallback<std::string()> system_profile_recorder_;
std::map<std::string, base::ObserverList<BackgroundTracingRule>>
named_trigger_observers_;
// Note, these sets are not mutated during iteration so it is okay to not use
// base::ObserverList.
std::set<raw_ptr<EnabledStateTestObserver, SetExperimental>>
background_tracing_observers_;
std::set<raw_ptr<tracing::mojom::BackgroundTracingAgent, SetExperimental>>
agents_;
std::set<raw_ptr<AgentObserver, SetExperimental>> agent_observers_;
std::unique_ptr<PreferenceManager> preferences_;
std::map<int, mojo::Remote<tracing::mojom::BackgroundTracingAgentProvider>>
pending_agents_;
ScenarioCountMap scenario_saved_counts_;
// Task runner on which |trace_database_| lives.
scoped_refptr<base::SequencedTaskRunner> database_task_runner_;
// This contains all the traces saved locally.
std::unique_ptr<TraceReportDatabase, base::OnTaskRunnerDeleter>
trace_database_;
std::optional<NewTraceReport> trace_report_to_upload_;
// Timer to delete traces older than 2 weeks.
base::RepeatingTimer clean_database_timer_;
// All the upload limits below are set for uncompressed trace log. On
// compression the data size usually reduces by 3x for size < 10MB, and the
// compression ratio grows up to 8x if the buffer size is around 100MB.
size_t upload_limit_network_kb_ = 1024;
size_t upload_limit_kb_ = kDefaultUploadLimitKb;
bool force_uploads_ = false;
base::WeakPtrFactory<BackgroundTracingManagerImpl> weak_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_TRACING_BACKGROUND_TRACING_MANAGER_IMPL_H_