Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2015 The Chromium Authors |
simonhatch | 0b01619 | 2015-05-22 19:14:02 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "content/browser/tracing/background_tracing_manager_impl.h" |
| 6 | |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 7 | #include <optional> |
dcheng | 36b6aec9 | 2015-12-26 06:16:36 | [diff] [blame] | 8 | #include <utility> |
| 9 | |
oysteine | b02d1809 | 2015-10-27 23:29:42 | [diff] [blame] | 10 | #include "base/command_line.h" |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 11 | #include "base/files/file_path.h" |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 12 | #include "base/functional/callback_helpers.h" |
Oksana Zhuravlova | e0202790 | 2020-10-27 18:44:32 | [diff] [blame] | 13 | #include "base/json/json_reader.h" |
simonhatch | 0cc9fee | 2015-06-15 22:26:19 | [diff] [blame] | 14 | #include "base/json/json_writer.h" |
fdoray | 7a8954a4 | 2016-06-07 04:28:38 | [diff] [blame] | 15 | #include "base/location.h" |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 16 | #include "base/memory/weak_ptr.h" |
Yash Joshi | d3da59f0 | 2023-03-23 22:24:48 | [diff] [blame] | 17 | #include "base/metrics/field_trial_params.h" |
Etienne Pierre-doray | 97f2a83 | 2024-04-05 15:55:55 | [diff] [blame] | 18 | #include "base/metrics/histogram_functions.h" |
oysteine | 341f2fb | 2015-06-11 03:53:53 | [diff] [blame] | 19 | #include "base/metrics/histogram_macros.h" |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 20 | #include "base/no_destructor.h" |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 21 | #include "base/path_service.h" |
Etienne Pierre-doray | 88cce9f | 2024-03-21 01:22:17 | [diff] [blame] | 22 | #include "base/strings/stringprintf.h" |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 23 | #include "base/task/bind_post_task.h" |
Patrick Monette | 643cdf6 | 2021-10-15 19:13:42 | [diff] [blame] | 24 | #include "base/task/single_thread_task_runner.h" |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 25 | #include "base/threading/sequence_bound.h" |
fmeawad | 743fcdf | 2015-06-03 23:55:34 | [diff] [blame] | 26 | #include "base/time/time.h" |
Etienne Pierre-doray | 67d8019 | 2024-11-14 21:52:47 | [diff] [blame] | 27 | #include "base/tracing/trace_time.h" |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 28 | #include "base/uuid.h" |
Ehsan Chiniforooshan | c77b44e | 2017-10-10 18:12:10 | [diff] [blame] | 29 | #include "base/values.h" |
ssid | 3e887900 | 2020-06-11 08:23:56 | [diff] [blame] | 30 | #include "build/build_config.h" |
Etienne Pierre-doray | 3dc2c7dc | 2025-06-12 12:06:33 | [diff] [blame] | 31 | #include "components/tracing/common/background_tracing_state_manager.h" |
Etienne Pierre-doray | 358170f | 2024-01-09 17:01:20 | [diff] [blame] | 32 | #include "components/variations/hashing.h" |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 33 | #include "content/browser/tracing/background_tracing_agent_client_impl.h" |
oysteine | f4ce0b06 | 2015-08-26 01:33:06 | [diff] [blame] | 34 | #include "content/browser/tracing/background_tracing_rule.h" |
Etienne Pierre-doray | 6db6af4f | 2025-06-05 14:20:59 | [diff] [blame] | 35 | #include "content/browser/tracing/trace_report_database.h" |
| 36 | #include "content/browser/tracing/trace_upload_list.h" |
caseq | 2fe929b | 2016-07-13 20:23:12 | [diff] [blame] | 37 | #include "content/browser/tracing/tracing_controller_impl.h" |
Etienne Pierre-doray | 23fe82c5 | 2024-11-25 17:57:46 | [diff] [blame] | 38 | #include "content/browser/tracing/triggers_data_source.h" |
Ken Rockot | 62fb435 | 2019-07-18 16:03:38 | [diff] [blame] | 39 | #include "content/common/child_process.mojom.h" |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 40 | #include "content/public/browser/browser_child_process_host.h" |
Eric Seckler | 8652dcd5 | 2018-09-20 10:42:28 | [diff] [blame] | 41 | #include "content/public/browser/browser_task_traits.h" |
simonhatch | 0b01619 | 2015-05-22 19:14:02 | [diff] [blame] | 42 | #include "content/public/browser/browser_thread.h" |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 43 | #include "content/public/browser/child_process_data.h" |
Will Harris | cd57b83 | 2023-01-05 20:03:10 | [diff] [blame] | 44 | #include "content/public/browser/child_process_host.h" |
oysteine | 386fc9e | 2015-06-07 18:45:41 | [diff] [blame] | 45 | #include "content/public/browser/content_browser_client.h" |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 46 | #include "content/public/browser/render_process_host.h" |
oysteine | 386fc9e | 2015-06-07 18:45:41 | [diff] [blame] | 47 | #include "content/public/common/content_client.h" |
oysteine | b02d1809 | 2015-10-27 23:29:42 | [diff] [blame] | 48 | #include "content/public/common/content_switches.h" |
Etienne Pierre-doray | 917135d | 2023-08-01 19:11:38 | [diff] [blame] | 49 | #include "net/base/network_change_notifier.h" |
Etienne Pierre-doray | f3fd9e8 | 2024-06-12 16:40:35 | [diff] [blame] | 50 | #include "services/tracing/public/cpp/trace_startup_config.h" |
Oystein Eftevaag | 2f3043e | 2019-03-12 18:25:32 | [diff] [blame] | 51 | #include "services/tracing/public/cpp/tracing_features.h" |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 52 | #include "third_party/zlib/google/compression_utils.h" |
simonhatch | 0b01619 | 2015-05-22 19:14:02 | [diff] [blame] | 53 | |
| 54 | namespace content { |
| 55 | |
Chris Hamilton | 4ec6fd31 | 2021-03-16 01:02:40 | [diff] [blame] | 56 | namespace { |
Etienne Pierre-doray | d05d46c | 2024-05-24 17:13:10 | [diff] [blame] | 57 | // The time to live of a trace report is currently 14 days. |
Etienne Pierre-doray | f8f587c | 2024-12-06 19:39:00 | [diff] [blame] | 58 | constexpr base::TimeDelta kTraceReportTimeToLive = base::Days(14); |
| 59 | // The time to live of uploaded trace content is 2 days. |
| 60 | constexpr base::TimeDelta kUploadedTraceContentTimeToLive = base::Days(2); |
Etienne Pierre-doray | 064c0340 | 2024-08-22 20:17:17 | [diff] [blame] | 61 | // We limit the overall number of traces. |
Etienne Pierre-doray | f8f587c | 2024-12-06 19:39:00 | [diff] [blame] | 62 | constexpr size_t kMaxTraceContent = 200; |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 63 | // We limit uploads of 1 trace per scenario over a period of 7 days. Since |
| 64 | // traces live in the database for longer than 7 days, their TTL doesn't affect |
| 65 | // this unless the database is manually cleared. |
Etienne Pierre-doray | f8f587c | 2024-12-06 19:39:00 | [diff] [blame] | 66 | constexpr base::TimeDelta kMinTimeUntilNextUpload = base::Days(7); |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 67 | // We limit the overall number of traces per scenario saved to the database at |
Etienne Pierre-doray | 064c0340 | 2024-08-22 20:17:17 | [diff] [blame] | 68 | // 100 per day. |
Etienne Pierre-doray | f8f587c | 2024-12-06 19:39:00 | [diff] [blame] | 69 | constexpr size_t kMaxTracesPerScenario = 100; |
| 70 | constexpr base::TimeDelta kMaxTracesPerScenarioDuration = base::Days(1); |
Chris Hamilton | 4ec6fd31 | 2021-03-16 01:02:40 | [diff] [blame] | 71 | |
Etienne Pierre-doray | 44477e15 | 2023-07-05 14:18:27 | [diff] [blame] | 72 | // |g_background_tracing_manager| is intentionally leaked on shutdown. |
| 73 | BackgroundTracingManager* g_background_tracing_manager = nullptr; |
| 74 | BackgroundTracingManagerImpl* g_background_tracing_manager_impl = nullptr; |
| 75 | |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 76 | void OpenDatabaseOnDatabaseTaskRunner( |
| 77 | TraceReportDatabase* database, |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 78 | std::optional<base::FilePath> database_dir, |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 79 | base::OnceCallback<void(BackgroundTracingManagerImpl::ScenarioCountMap, |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 80 | std::optional<BaseTraceReport>, |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 81 | bool)> on_database_created) { |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 82 | if (database->is_initialized()) { |
| 83 | return; |
| 84 | } |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 85 | bool success; |
| 86 | if (!database_dir) { |
| 87 | success = database->OpenDatabaseInMemoryForTesting(); // IN-TEST |
| 88 | } else { |
| 89 | success = database->OpenDatabase(*database_dir); |
| 90 | } |
Etienne Pierre-doray | b47f9071 | 2024-10-31 16:38:00 | [diff] [blame] | 91 | std::optional<NewTraceReport> report_to_upload = |
| 92 | database->GetNextReportPendingUpload(); |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 93 | GetUIThreadTaskRunner({})->PostTask( |
Etienne Pierre-doray | d05d46c | 2024-05-24 17:13:10 | [diff] [blame] | 94 | FROM_HERE, |
| 95 | base::BindOnce(std::move(on_database_created), |
| 96 | database->GetScenarioCountsSince( |
| 97 | base::Time::Now() - kMaxTracesPerScenarioDuration), |
| 98 | std::move(report_to_upload), success)); |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 99 | } |
| 100 | |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 101 | void AddTraceOnDatabaseTaskRunner( |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 102 | TraceReportDatabase* database, |
| 103 | std::string&& serialized_trace, |
Etienne Pierre-doray | f5690182 | 2023-09-22 19:54:12 | [diff] [blame] | 104 | std::string&& serialized_system_profile, |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 105 | BaseTraceReport base_report, |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 106 | bool should_save_trace, |
Etienne Pierre-doray | 749ed49c | 2024-10-15 18:19:13 | [diff] [blame] | 107 | bool force_upload, |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 108 | base::OnceCallback<void(std::optional<BaseTraceReport>, bool)> |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 109 | on_trace_saved) { |
| 110 | if (!database->is_initialized()) { |
| 111 | return; |
| 112 | } |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 113 | base::Time since = base::Time::Now() - kMinTimeUntilNextUpload; |
Etienne Pierre-doray | 1415b3893 | 2025-02-07 15:39:44 | [diff] [blame] | 114 | auto upload_count = database->UploadCountSince( |
| 115 | base_report.scenario_name, base_report.upload_rule_name, since); |
Etienne Pierre-doray | 749ed49c | 2024-10-15 18:19:13 | [diff] [blame] | 116 | if (base_report.skip_reason == SkipUploadReason::kNoSkip && !force_upload && |
| 117 | upload_count && *upload_count > 0) { |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 118 | base_report.skip_reason = SkipUploadReason::kScenarioQuotaExceeded; |
| 119 | if (!should_save_trace) { |
| 120 | return; |
| 121 | } |
| 122 | } |
| 123 | |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 124 | std::string compressed_trace; |
| 125 | bool success = compression::GzipCompress(serialized_trace, &compressed_trace); |
| 126 | if (success) { |
Etienne Pierre-doray | b47f9071 | 2024-10-31 16:38:00 | [diff] [blame] | 127 | NewTraceReport trace_report = base_report; |
| 128 | trace_report.trace_content = std::move(compressed_trace); |
| 129 | trace_report.system_profile = std::move(serialized_system_profile); |
| 130 | success = database->AddTrace(trace_report); |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 131 | } |
Etienne Pierre-doray | b47f9071 | 2024-10-31 16:38:00 | [diff] [blame] | 132 | auto report_to_upload = database->GetNextReportPendingUpload(); |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 133 | GetUIThreadTaskRunner({})->PostTask( |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 134 | FROM_HERE, base::BindOnce(std::move(on_trace_saved), |
| 135 | std::move(report_to_upload), success)); |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 136 | } |
| 137 | |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 138 | void OnUploadCompleteOnDatabaseTaskRunner( |
| 139 | TraceReportDatabase* database, |
| 140 | BaseTraceReport base_report, |
| 141 | base::OnceCallback<void(std::optional<BaseTraceReport>, bool)> |
| 142 | on_finalize_complete) { |
| 143 | base::Token uuid = base_report.uuid; |
| 144 | base::UmaHistogramSparse("Tracing.Background.Scenario.Upload", |
| 145 | variations::HashName(base_report.scenario_name)); |
| 146 | std::optional<ClientTraceReport> next_report; |
| 147 | if (database->UploadComplete(uuid, base::Time::Now())) { |
| 148 | next_report = database->GetNextReportPendingUpload(); |
| 149 | } |
| 150 | GetUIThreadTaskRunner({})->PostTask( |
| 151 | FROM_HERE, base::BindOnce(std::move(on_finalize_complete), |
| 152 | std::move(next_report), true)); |
| 153 | } |
| 154 | |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 155 | void GetProtoValueOnDatabaseTaskRunner( |
| 156 | TraceReportDatabase* database, |
Etienne Pierre-doray | 3d11c68d | 2024-11-15 17:51:57 | [diff] [blame] | 157 | BaseTraceReport base_report, |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 158 | base::OnceCallback<void(std::optional<std::string>, |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 159 | std::optional<std::string>, |
| 160 | base::OnceClosure)> receive_callback, |
| 161 | base::OnceClosure upload_complete) { |
Etienne Pierre-doray | 3d11c68d | 2024-11-15 17:51:57 | [diff] [blame] | 162 | base::Token uuid = base_report.uuid; |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 163 | auto compressed_trace_content = database->GetTraceContent(uuid); |
| 164 | if (!compressed_trace_content) { |
| 165 | std::move(receive_callback) |
| 166 | .Run(std::nullopt, std::nullopt, base::NullCallback()); |
| 167 | } else { |
| 168 | auto serialized_system_profile = database->GetSystemProfile(uuid); |
| 169 | std::move(receive_callback) |
| 170 | .Run(std::move(compressed_trace_content), |
| 171 | std::move(serialized_system_profile), std::move(upload_complete)); |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 172 | } |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 173 | } |
| 174 | |
Etienne Pierre-doray | 0af80e7 | 2024-06-28 18:25:29 | [diff] [blame] | 175 | class PreferenceManagerImpl |
| 176 | : public BackgroundTracingManagerImpl::PreferenceManager { |
| 177 | public: |
| 178 | bool GetBackgroundStartupTracingEnabled() const override { |
| 179 | return tracing::TraceStartupConfig::GetInstance().IsEnabled() && |
| 180 | tracing::TraceStartupConfig::GetInstance().GetSessionOwner() == |
| 181 | tracing::TraceStartupConfig::SessionOwner::kBackgroundTracing; |
| 182 | } |
| 183 | }; |
| 184 | |
Etienne Pierre-doray | 67d8019 | 2024-11-14 21:52:47 | [diff] [blame] | 185 | // Emits background tracing metadata as a data source. |
| 186 | class BackgroundMetadataDataSource |
| 187 | : public perfetto::DataSource<BackgroundMetadataDataSource> { |
| 188 | public: |
Etienne Pierre-doray | f5a089b | 2025-03-03 15:16:19 | [diff] [blame] | 189 | static constexpr bool kRequiresCallbacksUnderLock = false; |
| 190 | |
Etienne Pierre-doray | 67d8019 | 2024-11-14 21:52:47 | [diff] [blame] | 191 | static void Register() { |
| 192 | perfetto::DataSourceDescriptor desc; |
| 193 | desc.set_name("org.chromium.background_scenario_metadata"); |
Etienne Pierre-doray | 9676d603 | 2025-01-21 16:44:25 | [diff] [blame] | 194 | CHECK(perfetto::DataSource<BackgroundMetadataDataSource>::Register(desc)); |
Etienne Pierre-doray | 67d8019 | 2024-11-14 21:52:47 | [diff] [blame] | 195 | } |
| 196 | |
| 197 | static void EmitMetadata(TracingScenario* scenario) { |
| 198 | Trace([&](TraceContext ctx) { |
| 199 | auto packet = ctx.NewTracePacket(); |
| 200 | packet->set_timestamp( |
| 201 | TRACE_TIME_TICKS_NOW().since_origin().InNanoseconds()); |
| 202 | packet->set_timestamp_clock_id(base::tracing::kTraceClockId); |
| 203 | auto* chrome_metadata = packet->set_chrome_metadata(); |
| 204 | scenario->GenerateMetadataProto(chrome_metadata); |
Etienne Pierre-doray | f5a089b | 2025-03-03 15:16:19 | [diff] [blame] | 205 | packet->Finalize(); |
| 206 | ctx.Flush(); |
Etienne Pierre-doray | 67d8019 | 2024-11-14 21:52:47 | [diff] [blame] | 207 | }); |
| 208 | } |
| 209 | }; |
| 210 | |
Chris Hamilton | 4ec6fd31 | 2021-03-16 01:02:40 | [diff] [blame] | 211 | } // namespace |
| 212 | |
| 213 | // static |
Etienne Pierre-doray | 44477e15 | 2023-07-05 14:18:27 | [diff] [blame] | 214 | std::unique_ptr<BackgroundTracingManager> |
Etienne Pierre-doray | 3dc2c7dc | 2025-06-12 12:06:33 | [diff] [blame] | 215 | BackgroundTracingManager::CreateInstance(TracingDelegate* delegate) { |
| 216 | return std::make_unique<BackgroundTracingManagerImpl>(delegate); |
Etienne Pierre-doray | 44477e15 | 2023-07-05 14:18:27 | [diff] [blame] | 217 | } |
| 218 | |
| 219 | // static |
Oksana Zhuravlova | 872a5a6f | 2022-06-08 18:15:29 | [diff] [blame] | 220 | BackgroundTracingManager& BackgroundTracingManager::GetInstance() { |
Etienne Pierre-doray | 44477e15 | 2023-07-05 14:18:27 | [diff] [blame] | 221 | CHECK_NE(nullptr, g_background_tracing_manager); |
| 222 | return *g_background_tracing_manager; |
| 223 | } |
| 224 | |
| 225 | // static |
| 226 | void BackgroundTracingManager::SetInstance( |
| 227 | BackgroundTracingManager* tracing_manager) { |
| 228 | DCHECK(g_background_tracing_manager == nullptr || tracing_manager == nullptr); |
| 229 | g_background_tracing_manager = tracing_manager; |
| 230 | } |
| 231 | |
| 232 | // static |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 233 | void BackgroundTracingManagerImpl::RecordMetric(Metrics metric) { |
oysteine | 341f2fb | 2015-06-11 03:53:53 | [diff] [blame] | 234 | UMA_HISTOGRAM_ENUMERATION("Tracing.Background.ScenarioState", metric, |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 235 | Metrics::NUMBER_OF_BACKGROUND_TRACING_METRICS); |
oysteine | 341f2fb | 2015-06-11 03:53:53 | [diff] [blame] | 236 | } |
| 237 | |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 238 | // static |
Oksana Zhuravlova | 872a5a6f | 2022-06-08 18:15:29 | [diff] [blame] | 239 | BackgroundTracingManagerImpl& BackgroundTracingManagerImpl::GetInstance() { |
Etienne Pierre-doray | 44477e15 | 2023-07-05 14:18:27 | [diff] [blame] | 240 | CHECK_NE(nullptr, g_background_tracing_manager_impl); |
| 241 | return *g_background_tracing_manager_impl; |
simonhatch | 0b01619 | 2015-05-22 19:14:02 | [diff] [blame] | 242 | } |
| 243 | |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 244 | // static |
| 245 | void BackgroundTracingManagerImpl::ActivateForProcess( |
Darin Fisher | 0e4fc2e | 2019-06-13 02:19:18 | [diff] [blame] | 246 | int child_process_id, |
Ken Rockot | 62fb435 | 2019-07-18 16:03:38 | [diff] [blame] | 247 | mojom::ChildProcess* child_process) { |
Darin Fisher | 53ceb1829 | 2019-06-21 22:26:15 | [diff] [blame] | 248 | // NOTE: Called from any thread. |
| 249 | |
Darin Fisher | 0e4fc2e | 2019-06-13 02:19:18 | [diff] [blame] | 250 | mojo::PendingRemote<tracing::mojom::BackgroundTracingAgentProvider> |
| 251 | pending_provider; |
Ken Rockot | 62fb435 | 2019-07-18 16:03:38 | [diff] [blame] | 252 | child_process->GetBackgroundTracingAgentProvider( |
Darin Fisher | 0e4fc2e | 2019-06-13 02:19:18 | [diff] [blame] | 253 | pending_provider.InitWithNewPipeAndPassReceiver()); |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 254 | |
Gabriel Charette | e7cdc5cd | 2020-05-27 23:35:05 | [diff] [blame] | 255 | GetUIThreadTaskRunner({})->PostTask( |
| 256 | FROM_HERE, base::BindOnce(&BackgroundTracingManagerImpl::AddPendingAgent, |
Wanchang Ryu | 342162a | 2020-02-27 19:31:25 | [diff] [blame] | 257 | child_process_id, std::move(pending_provider))); |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 258 | } |
| 259 | |
Etienne Pierre-doray | 3dc2c7dc | 2025-06-12 12:06:33 | [diff] [blame] | 260 | BackgroundTracingManagerImpl::BackgroundTracingManagerImpl( |
| 261 | TracingDelegate* delegate) |
| 262 | : delegate_(delegate), |
| 263 | state_manager_(delegate_->CreateStateManager()), |
Alex Attar | 9e640b2 | 2023-08-25 14:44:06 | [diff] [blame] | 264 | database_task_runner_(base::ThreadPool::CreateSequencedTaskRunner( |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 265 | {base::MayBlock(), base::TaskPriority::USER_VISIBLE, |
Alex Attar | 9e640b2 | 2023-08-25 14:44:06 | [diff] [blame] | 266 | base::TaskShutdownBehavior::BLOCK_SHUTDOWN})), |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 267 | trace_database_(nullptr, |
Alex Attar | 9e640b2 | 2023-08-25 14:44:06 | [diff] [blame] | 268 | base::OnTaskRunnerDeleter(database_task_runner_)) { |
Etienne Pierre-doray | 6b4f784 | 2024-02-15 18:34:01 | [diff] [blame] | 269 | BackgroundTracingManager::SetInstance(this); |
| 270 | NamedTriggerManager::SetInstance(this); |
Etienne Pierre-doray | 44477e15 | 2023-07-05 14:18:27 | [diff] [blame] | 271 | g_background_tracing_manager_impl = this; |
Etienne Pierre-doray | 0af80e7 | 2024-06-28 18:25:29 | [diff] [blame] | 272 | preferences_ = std::make_unique<PreferenceManagerImpl>(); |
Etienne Pierre-doray | 9676d603 | 2025-01-21 16:44:25 | [diff] [blame] | 273 | if (perfetto::Tracing::IsInitialized()) { |
| 274 | AddMetadataGeneratorFunction(); |
| 275 | } |
ssid | eb54962 | 2017-03-29 21:46:00 | [diff] [blame] | 276 | } |
simonhatch | 0b01619 | 2015-05-22 19:14:02 | [diff] [blame] | 277 | |
Etienne Pierre-doray | 44477e15 | 2023-07-05 14:18:27 | [diff] [blame] | 278 | BackgroundTracingManagerImpl::~BackgroundTracingManagerImpl() { |
| 279 | DCHECK_EQ(this, g_background_tracing_manager_impl); |
Etienne Pierre-doray | 45af150 | 2025-02-26 15:57:05 | [diff] [blame] | 280 | DisableScenarios(); |
Etienne Pierre-doray | 6b4f784 | 2024-02-15 18:34:01 | [diff] [blame] | 281 | BackgroundTracingManager::SetInstance(nullptr); |
| 282 | NamedTriggerManager::SetInstance(nullptr); |
Etienne Pierre-doray | 44477e15 | 2023-07-05 14:18:27 | [diff] [blame] | 283 | g_background_tracing_manager_impl = nullptr; |
| 284 | } |
simonhatch | 0b01619 | 2015-05-22 19:14:02 | [diff] [blame] | 285 | |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 286 | void BackgroundTracingManagerImpl::OpenDatabaseIfExists() { |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 287 | if (trace_database_) { |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 288 | return; |
| 289 | } |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 290 | std::optional<base::FilePath> database_dir = |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 291 | GetContentClient()->browser()->GetLocalTracesDirectory(); |
| 292 | if (!database_dir.has_value()) { |
| 293 | return; |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 294 | } |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 295 | trace_database_ = {new TraceReportDatabase, |
| 296 | base::OnTaskRunnerDeleter(database_task_runner_)}; |
| 297 | database_task_runner_->PostTask( |
| 298 | FROM_HERE, |
| 299 | base::BindOnce( |
| 300 | [](TraceReportDatabase* trace_database, base::FilePath path) { |
| 301 | trace_database->OpenDatabaseIfExists(path); |
| 302 | }, |
| 303 | base::Unretained(trace_database_.get()), database_dir.value())); |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 304 | } |
| 305 | |
| 306 | void BackgroundTracingManagerImpl::GetAllTraceReports( |
| 307 | GetReportsCallback callback) { |
| 308 | if (!trace_database_) { |
| 309 | std::move(callback).Run({}); |
| 310 | return; |
| 311 | } |
| 312 | |
| 313 | database_task_runner_->PostTaskAndReplyWithResult( |
| 314 | FROM_HERE, |
| 315 | base::BindOnce(&TraceReportDatabase::GetAllReports, |
| 316 | base::Unretained(trace_database_.get())), |
| 317 | std::move(callback)); |
| 318 | } |
| 319 | |
| 320 | void BackgroundTracingManagerImpl::DeleteSingleTrace( |
Alex Attar | 3c0b1af0 | 2023-09-21 15:16:53 | [diff] [blame] | 321 | const base::Token& trace_uuid, |
| 322 | FinishedProcessingCallback callback) { |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 323 | if (!trace_database_) { |
| 324 | std::move(callback).Run(false); |
| 325 | return; |
| 326 | } |
| 327 | |
| 328 | database_task_runner_->PostTaskAndReplyWithResult( |
| 329 | FROM_HERE, |
| 330 | base::BindOnce(&TraceReportDatabase::DeleteTrace, |
| 331 | base::Unretained(trace_database_.get()), trace_uuid), |
| 332 | std::move(callback)); |
| 333 | } |
| 334 | |
| 335 | void BackgroundTracingManagerImpl::DeleteAllTraces( |
Jose Dapena Paz | b19e966 | 2023-09-15 06:47:24 | [diff] [blame] | 336 | TraceUploadList::FinishedProcessingCallback callback) { |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 337 | if (!trace_database_) { |
| 338 | std::move(callback).Run(false); |
| 339 | return; |
| 340 | } |
| 341 | |
| 342 | database_task_runner_->PostTaskAndReplyWithResult( |
| 343 | FROM_HERE, |
| 344 | base::BindOnce(&TraceReportDatabase::DeleteAllTraces, |
| 345 | base::Unretained(trace_database_.get())), |
| 346 | std::move(callback)); |
| 347 | } |
| 348 | |
| 349 | void BackgroundTracingManagerImpl::UserUploadSingleTrace( |
Alex Attar | 3c0b1af0 | 2023-09-21 15:16:53 | [diff] [blame] | 350 | const base::Token& trace_uuid, |
Jose Dapena Paz | b19e966 | 2023-09-15 06:47:24 | [diff] [blame] | 351 | TraceUploadList::FinishedProcessingCallback callback) { |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 352 | if (!trace_database_) { |
| 353 | std::move(callback).Run(false); |
| 354 | return; |
| 355 | } |
| 356 | |
| 357 | database_task_runner_->PostTaskAndReplyWithResult( |
| 358 | FROM_HERE, |
| 359 | base::BindOnce(&TraceReportDatabase::UserRequestedUpload, |
| 360 | base::Unretained(trace_database_.get()), trace_uuid), |
| 361 | std::move(callback)); |
| 362 | } |
| 363 | |
Alex Attar | 3c0b1af0 | 2023-09-21 15:16:53 | [diff] [blame] | 364 | void BackgroundTracingManagerImpl::DownloadTrace(const base::Token& trace_uuid, |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 365 | GetProtoCallback callback) { |
| 366 | if (!trace_database_) { |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 367 | std::move(callback).Run(std::nullopt); |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 368 | return; |
| 369 | } |
| 370 | |
| 371 | database_task_runner_->PostTaskAndReplyWithResult( |
| 372 | FROM_HERE, |
Etienne Pierre-doray | f5690182 | 2023-09-22 19:54:12 | [diff] [blame] | 373 | base::BindOnce(&TraceReportDatabase::GetTraceContent, |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 374 | base::Unretained(trace_database_.get()), trace_uuid), |
Alex Attar | 3d5802d | 2023-09-13 14:47:44 | [diff] [blame] | 375 | base::BindOnce( |
| 376 | [](GetProtoCallback callback, |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 377 | const std::optional<std::string>& result) { |
Alex Attar | 3d5802d | 2023-09-13 14:47:44 | [diff] [blame] | 378 | if (result) { |
| 379 | std::move(callback).Run(base::span<const char>(*result)); |
| 380 | } else { |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 381 | std::move(callback).Run(std::nullopt); |
Alex Attar | 3d5802d | 2023-09-13 14:47:44 | [diff] [blame] | 382 | } |
| 383 | }, |
| 384 | std::move(callback))); |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 385 | } |
| 386 | |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 387 | void BackgroundTracingManagerImpl::OnTraceDatabaseCreated( |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 388 | ScenarioCountMap scenario_saved_counts, |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 389 | std::optional<BaseTraceReport> trace_to_upload, |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 390 | bool creation_result) { |
| 391 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 392 | scenario_saved_counts_ = std::move(scenario_saved_counts); |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 393 | trace_report_to_upload_ = std::move(trace_to_upload); |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 394 | if (!creation_result) { |
| 395 | RecordMetric(Metrics::DATABASE_INITIALIZATION_FAILED); |
Alex Attar | cc5eebb | 2023-08-11 16:35:55 | [diff] [blame] | 396 | return; |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 397 | } |
Etienne Pierre-doray | d05d46c | 2024-05-24 17:13:10 | [diff] [blame] | 398 | CleanDatabase(); |
Alex Attar | cc5eebb | 2023-08-11 16:35:55 | [diff] [blame] | 399 | clean_database_timer_.Start( |
| 400 | FROM_HERE, base::Days(1), |
| 401 | base::BindRepeating(&BackgroundTracingManagerImpl::CleanDatabase, |
| 402 | weak_factory_.GetWeakPtr())); |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 403 | } |
| 404 | |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 405 | void BackgroundTracingManagerImpl::OnTraceDatabaseUpdated( |
| 406 | ScenarioCountMap scenario_saved_counts) { |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 407 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 408 | scenario_saved_counts_ = std::move(scenario_saved_counts); |
| 409 | } |
| 410 | |
| 411 | void BackgroundTracingManagerImpl::OnTraceSaved( |
| 412 | const std::string& scenario_name, |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 413 | std::optional<BaseTraceReport> trace_to_upload, |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 414 | bool success) { |
| 415 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 416 | RecordMetric(success ? Metrics::SAVE_TRACE_SUCCEEDED |
| 417 | : Metrics::SAVE_TRACE_FAILED); |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 418 | trace_report_to_upload_ = std::move(trace_to_upload); |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 419 | if (success) { |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 420 | ++scenario_saved_counts_[scenario_name]; |
| 421 | } |
Ali Hijazi | 133b2d9 | 2024-02-09 14:01:52 | [diff] [blame] | 422 | for (EnabledStateTestObserver* observer : background_tracing_observers_) { |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 423 | observer->OnTraceSaved(); |
| 424 | } |
| 425 | } |
| 426 | |
Ehsan Chiniforooshan | c77b44e | 2017-10-10 18:12:10 | [diff] [blame] | 427 | void BackgroundTracingManagerImpl::AddMetadataGeneratorFunction() { |
Etienne Pierre-doray | 67d8019 | 2024-11-14 21:52:47 | [diff] [blame] | 428 | BackgroundMetadataDataSource::Register(); |
Etienne Pierre-doray | 23fe82c5 | 2024-11-25 17:57:46 | [diff] [blame] | 429 | TriggersDataSource::Register(); |
Ehsan Chiniforooshan | c77b44e | 2017-10-10 18:12:10 | [diff] [blame] | 430 | } |
| 431 | |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 432 | bool BackgroundTracingManagerImpl::RequestActivateScenario() { |
| 433 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 434 | // Multi-scenarios sessions can't be initialized twice. |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 435 | DCHECK(field_scenarios_.empty()); |
Etienne Pierre-doray | 45af150 | 2025-02-26 15:57:05 | [diff] [blame] | 436 | DCHECK(enabled_scenarios_.empty()); |
| 437 | RecordMetric(Metrics::SCENARIO_ACTIVATION_REQUESTED); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 438 | |
Etienne Pierre-doray | a83afef | 2024-04-17 16:49:38 | [diff] [blame] | 439 | // Bail on scenario activation if trigger rules are already setup to be |
| 440 | // forwarded to system tracing. |
| 441 | if (!trigger_rules_.empty()) { |
| 442 | return false; |
| 443 | } |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 444 | |
| 445 | // If we don't have a high resolution timer available, traces will be |
| 446 | // too inaccurate to be useful. |
| 447 | if (!base::TimeTicks::IsHighResolution()) { |
| 448 | RecordMetric(Metrics::SCENARIO_ACTION_FAILED_LOWRES_CLOCK); |
| 449 | return false; |
| 450 | } |
| 451 | return true; |
| 452 | } |
| 453 | |
Etienne Pierre-doray | 45af150 | 2025-02-26 15:57:05 | [diff] [blame] | 454 | void BackgroundTracingManagerImpl::DisableScenarios() { |
| 455 | if (active_scenario_) { |
| 456 | enabled_scenarios_.clear(); |
| 457 | active_scenario_->Abort(); |
| 458 | } else { |
| 459 | for (auto& scenario : enabled_scenarios_) { |
| 460 | scenario->Disable(); |
| 461 | } |
| 462 | enabled_scenarios_.clear(); |
| 463 | } |
| 464 | for (auto& rule : trigger_rules_) { |
| 465 | rule->Uninstall(); |
| 466 | } |
| 467 | trigger_rules_.clear(); |
| 468 | } |
| 469 | |
Etienne Pierre-doray | 69e9361 | 2023-09-18 21:39:33 | [diff] [blame] | 470 | void BackgroundTracingManagerImpl::SetReceiveCallback( |
| 471 | ReceiveCallback receive_callback) { |
| 472 | receive_callback_ = std::move(receive_callback); |
| 473 | } |
| 474 | |
Etienne Pierre-doray | a83afef | 2024-04-17 16:49:38 | [diff] [blame] | 475 | bool BackgroundTracingManagerImpl::InitializePerfettoTriggerRules( |
| 476 | const perfetto::protos::gen::TracingTriggerRulesConfig& config) { |
| 477 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 478 | // Trigger rules can't be initialized twice. |
| 479 | DCHECK(trigger_rules_.empty()); |
Etienne Pierre-doray | a83afef | 2024-04-17 16:49:38 | [diff] [blame] | 480 | |
| 481 | // Bail on setting up trigger rules if scenarios are already enabled. |
| 482 | if (!enabled_scenarios_.empty()) { |
| 483 | return false; |
| 484 | } |
| 485 | |
| 486 | if (!BackgroundTracingRule::Append(config.rules(), trigger_rules_)) { |
| 487 | return false; |
| 488 | } |
| 489 | for (auto& rule : trigger_rules_) { |
| 490 | rule->Install(base::BindRepeating([](const BackgroundTracingRule* rule) { |
Etienne Pierre-doray | b1a3a80 | 2024-07-16 16:33:54 | [diff] [blame] | 491 | base::UmaHistogramSparse("Tracing.Background.Perfetto.Trigger", |
Etienne Pierre-doray | cf6f244 | 2024-12-03 18:23:47 | [diff] [blame] | 492 | variations::HashName(rule->rule_name())); |
| 493 | perfetto::Tracing::ActivateTriggers({rule->rule_name()}, |
Etienne Pierre-doray | a83afef | 2024-04-17 16:49:38 | [diff] [blame] | 494 | /*ttl_ms=*/0); |
| 495 | return true; |
| 496 | })); |
| 497 | } |
| 498 | return true; |
| 499 | } |
| 500 | |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 501 | bool BackgroundTracingManagerImpl::InitializeFieldScenarios( |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 502 | const perfetto::protos::gen::ChromeFieldTracingConfig& config, |
Etienne Pierre-doray | 749ed49c | 2024-10-15 18:19:13 | [diff] [blame] | 503 | DataFiltering data_filtering, |
| 504 | bool force_uploads, |
| 505 | size_t upload_limit_kb) { |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 506 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 507 | if (!RequestActivateScenario()) { |
| 508 | return false; |
| 509 | } |
Etienne Pierre-doray | 749ed49c | 2024-10-15 18:19:13 | [diff] [blame] | 510 | force_uploads_ = force_uploads; |
| 511 | if (upload_limit_kb > 0) { |
| 512 | upload_limit_kb_ = upload_limit_kb; |
| 513 | } |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 514 | |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 515 | bool requires_anonymized_data = (data_filtering != NO_DATA_FILTERING); |
Etienne Pierre-doray | 72caf35 | 2023-09-28 04:05:06 | [diff] [blame] | 516 | bool enable_package_name_filter = |
| 517 | (data_filtering == ANONYMIZE_DATA_AND_FILTER_PACKAGE_NAME); |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 518 | InitializeTraceReportDatabase(); |
| 519 | |
Etienne Pierre-doray | 0af80e7 | 2024-06-28 18:25:29 | [diff] [blame] | 520 | if (preferences_->GetBackgroundStartupTracingEnabled()) { |
| 521 | perfetto::protos::gen::ScenarioConfig scenario_config; |
| 522 | scenario_config.set_scenario_name("Startup"); |
| 523 | *scenario_config.mutable_trace_config() = |
| 524 | tracing::TraceStartupConfig::GetDefaultBackgroundStartupConfig(); |
| 525 | scenario_config.add_start_rules()->set_manual_trigger_name( |
| 526 | base::trace_event::kStartupTracingTriggerName); |
| 527 | scenario_config.add_upload_rules()->set_delay_ms(30000); |
| 528 | |
| 529 | // Startup tracing was already requested earlier for this scenario. |
| 530 | auto startup_scenario = TracingScenario::Create( |
| 531 | scenario_config, requires_anonymized_data, enable_package_name_filter, |
Etienne Pierre-doray | ffeda34 | 2024-11-05 21:47:47 | [diff] [blame] | 532 | /*is_local_scenario=*/false, |
Etienne Pierre-doray | 0af80e7 | 2024-06-28 18:25:29 | [diff] [blame] | 533 | /*request_startup_tracing=*/false, this); |
| 534 | field_scenarios_.push_back(std::move(startup_scenario)); |
| 535 | enabled_scenarios_.push_back(field_scenarios_.back().get()); |
| 536 | enabled_scenarios_.back()->Enable(); |
| 537 | } |
| 538 | |
Etienne Pierre-doray | e2c7dd8 | 2025-04-17 16:57:37 | [diff] [blame] | 539 | bool result = true; |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 540 | for (const auto& scenario_config : config.scenarios()) { |
Etienne Pierre-doray | ffeda34 | 2024-11-05 21:47:47 | [diff] [blame] | 541 | auto scenario = TracingScenario::Create( |
| 542 | scenario_config, requires_anonymized_data, |
| 543 | /*is_local_scenario=*/false, enable_package_name_filter, true, this); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 544 | if (!scenario) { |
Etienne Pierre-doray | e2c7dd8 | 2025-04-17 16:57:37 | [diff] [blame] | 545 | base::UmaHistogramSparse( |
| 546 | "Tracing.Background.Scenario.Invalid", |
| 547 | variations::HashName(scenario_config.scenario_name())); |
| 548 | result = false; |
| 549 | continue; |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 550 | } |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 551 | field_scenarios_.push_back(std::move(scenario)); |
| 552 | enabled_scenarios_.push_back(field_scenarios_.back().get()); |
| 553 | enabled_scenarios_.back()->Enable(); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 554 | } |
Etienne Pierre-doray | 0960910 | 2024-10-11 13:16:04 | [diff] [blame] | 555 | MaybeConstructPendingAgents(); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 556 | RecordMetric(Metrics::SCENARIO_ACTIVATED_SUCCESSFULLY); |
Etienne Pierre-doray | e2c7dd8 | 2025-04-17 16:57:37 | [diff] [blame] | 557 | return result; |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 558 | } |
| 559 | |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 560 | std::vector<std::string> BackgroundTracingManagerImpl::AddPresetScenarios( |
| 561 | const perfetto::protos::gen::ChromeFieldTracingConfig& config, |
| 562 | DataFiltering data_filtering) { |
Etienne Pierre-doray | bc32597e | 2025-04-22 14:12:57 | [diff] [blame] | 563 | return AddPresetScenariosImpl(config, data_filtering, false); |
| 564 | } |
| 565 | |
| 566 | std::vector<std::string> BackgroundTracingManagerImpl::OverwritePresetScenarios( |
| 567 | const perfetto::protos::gen::ChromeFieldTracingConfig& config, |
| 568 | DataFiltering data_filtering) { |
| 569 | return AddPresetScenariosImpl(config, data_filtering, true); |
| 570 | } |
| 571 | |
| 572 | std::vector<std::string> BackgroundTracingManagerImpl::AddPresetScenariosImpl( |
| 573 | const perfetto::protos::gen::ChromeFieldTracingConfig& config, |
| 574 | DataFiltering data_filtering, |
| 575 | bool overwrite_conflicts) { |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 576 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Etienne Pierre-doray | 45af150 | 2025-02-26 15:57:05 | [diff] [blame] | 577 | |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 578 | bool enable_privacy_filter = (data_filtering != NO_DATA_FILTERING); |
| 579 | bool enable_package_name_filter = |
| 580 | (data_filtering == ANONYMIZE_DATA_AND_FILTER_PACKAGE_NAME); |
| 581 | |
| 582 | std::vector<std::string> added_scenarios; |
Etienne Pierre-doray | b693f72 | 2025-06-18 21:50:03 | [diff] [blame] | 583 | std::set<raw_ptr<TracingScenario>> conflicting_scenarios_set; |
| 584 | std::vector<std::unique_ptr<TracingScenario>> conflicting_scenarios; |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 585 | for (const auto& scenario_config : config.scenarios()) { |
Etienne Pierre-doray | bc32597e | 2025-04-22 14:12:57 | [diff] [blame] | 586 | auto scenario = TracingScenario::Create( |
| 587 | scenario_config, enable_privacy_filter, /*is_local_scenario=*/true, |
| 588 | enable_package_name_filter, true, this); |
| 589 | if (!scenario) { |
| 590 | base::UmaHistogramSparse( |
| 591 | "Tracing.Background.Scenario.Invalid", |
| 592 | variations::HashName(scenario_config.scenario_name())); |
| 593 | continue; |
| 594 | } |
| 595 | |
Etienne Pierre-doray | b693f72 | 2025-06-18 21:50:03 | [diff] [blame] | 596 | if (auto it = preset_scenarios_.find(scenario_config.scenario_name()); |
| 597 | it != preset_scenarios_.end()) { |
| 598 | if (!overwrite_conflicts) { |
| 599 | continue; |
| 600 | } |
| 601 | if (active_scenario_ == it->second.get()) { |
| 602 | active_scenario_->Abort(); |
| 603 | active_scenario_ = nullptr; |
| 604 | conflicting_scenarios_set.insert(it->second.get()); |
| 605 | conflicting_scenarios.emplace_back(std::move(it->second)); |
| 606 | } else if (it->second->current_state() != |
| 607 | TracingScenario::State::kDisabled) { |
| 608 | it->second->Disable(); |
| 609 | conflicting_scenarios_set.insert(it->second.get()); |
| 610 | conflicting_scenarios.emplace_back(std::move(it->second)); |
| 611 | } |
| 612 | } |
| 613 | |
Etienne Pierre-doray | 6474806 | 2025-01-28 21:15:34 | [diff] [blame] | 614 | added_scenarios.push_back(scenario->scenario_name()); |
Etienne Pierre-doray | 45af150 | 2025-02-26 15:57:05 | [diff] [blame] | 615 | preset_scenarios_[scenario->scenario_name()] = std::move(scenario); |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 616 | } |
Etienne Pierre-doray | 38837fbc | 2025-03-24 19:35:48 | [diff] [blame] | 617 | if (!conflicting_scenarios.empty()) { |
| 618 | std::erase_if(enabled_scenarios_, [&](raw_ptr<TracingScenario> scenario) { |
Etienne Pierre-doray | b693f72 | 2025-06-18 21:50:03 | [diff] [blame] | 619 | return conflicting_scenarios_set.contains(scenario); |
Etienne Pierre-doray | 38837fbc | 2025-03-24 19:35:48 | [diff] [blame] | 620 | }); |
| 621 | } |
Etienne Pierre-doray | b693f72 | 2025-06-18 21:50:03 | [diff] [blame] | 622 | conflicting_scenarios_set.clear(); |
Etienne Pierre-doray | 38837fbc | 2025-03-24 19:35:48 | [diff] [blame] | 623 | |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 624 | return added_scenarios; |
| 625 | } |
| 626 | |
Etienne Pierre-doray | 6db6af4f | 2025-06-05 14:20:59 | [diff] [blame] | 627 | std::vector<traces_internals::mojom::ScenarioPtr> |
Etienne Pierre-doray | c5029de | 2025-05-27 15:48:54 | [diff] [blame] | 628 | BackgroundTracingManagerImpl::GetAllScenarios() const { |
Etienne Pierre-doray | 6db6af4f | 2025-06-05 14:20:59 | [diff] [blame] | 629 | std::vector<traces_internals::mojom::ScenarioPtr> result; |
Etienne Pierre-doray | c5029de | 2025-05-27 15:48:54 | [diff] [blame] | 630 | auto toMojoScenario = [this](TracingScenario* scenario) { |
Etienne Pierre-doray | 6db6af4f | 2025-06-05 14:20:59 | [diff] [blame] | 631 | auto new_scenario = traces_internals::mojom::Scenario::New(); |
Etienne Pierre-doray | 4804091 | 2024-08-20 19:12:35 | [diff] [blame] | 632 | new_scenario->scenario_name = scenario->scenario_name(); |
Etienne Pierre-doray | c5029de | 2025-05-27 15:48:54 | [diff] [blame] | 633 | new_scenario->description = scenario->description(); |
| 634 | new_scenario->is_local_scenario = scenario->is_local_scenario(); |
| 635 | new_scenario->is_enabled = base::Contains(enabled_scenarios_, scenario); |
| 636 | new_scenario->current_state = scenario->current_state(); |
| 637 | return new_scenario; |
| 638 | }; |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 639 | for (const auto& scenario : preset_scenarios_) { |
Etienne Pierre-doray | c5029de | 2025-05-27 15:48:54 | [diff] [blame] | 640 | result.push_back(toMojoScenario(scenario.second.get())); |
| 641 | } |
| 642 | for (const auto& scenario : field_scenarios_) { |
| 643 | result.push_back(toMojoScenario(scenario.get())); |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 644 | } |
| 645 | return result; |
| 646 | } |
| 647 | |
| 648 | bool BackgroundTracingManagerImpl::SetEnabledScenarios( |
| 649 | std::vector<std::string> enabled_scenarios) { |
Etienne Pierre-doray | 45af150 | 2025-02-26 15:57:05 | [diff] [blame] | 650 | DisableScenarios(); |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 651 | InitializeTraceReportDatabase(); |
| 652 | for (const std::string& hash : enabled_scenarios) { |
| 653 | auto it = preset_scenarios_.find(hash); |
| 654 | if (it == preset_scenarios_.end()) { |
| 655 | return false; |
| 656 | } |
| 657 | enabled_scenarios_.push_back(it->second.get()); |
| 658 | if (!active_scenario_) { |
| 659 | it->second->Enable(); |
| 660 | } |
| 661 | } |
Etienne Pierre-doray | 0960910 | 2024-10-11 13:16:04 | [diff] [blame] | 662 | MaybeConstructPendingAgents(); |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 663 | return true; |
| 664 | } |
| 665 | |
| 666 | std::vector<std::string> BackgroundTracingManagerImpl::GetEnabledScenarios() |
| 667 | const { |
| 668 | std::vector<std::string> scenario_hashes; |
| 669 | for (auto scenario : enabled_scenarios_) { |
Etienne Pierre-doray | 6474806 | 2025-01-28 21:15:34 | [diff] [blame] | 670 | scenario_hashes.push_back(scenario->scenario_name()); |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 671 | } |
| 672 | return scenario_hashes; |
| 673 | } |
| 674 | |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 675 | void BackgroundTracingManagerImpl::InitializeTraceReportDatabase( |
| 676 | bool open_in_memory) { |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 677 | std::optional<base::FilePath> database_dir; |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 678 | if (!trace_database_) { |
| 679 | trace_database_ = {new TraceReportDatabase, |
| 680 | base::OnTaskRunnerDeleter(database_task_runner_)}; |
| 681 | if (!open_in_memory) { |
| 682 | database_dir = GetContentClient()->browser()->GetLocalTracesDirectory(); |
| 683 | if (!database_dir.has_value()) { |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 684 | OnTraceDatabaseCreated({}, std::nullopt, false); |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 685 | return; |
| 686 | } |
| 687 | } |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 688 | } |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 689 | database_task_runner_->PostTask( |
| 690 | FROM_HERE, |
| 691 | base::BindOnce( |
| 692 | OpenDatabaseOnDatabaseTaskRunner, |
| 693 | base::Unretained(trace_database_.get()), std::move(database_dir), |
| 694 | base::BindOnce(&BackgroundTracingManagerImpl::OnTraceDatabaseCreated, |
| 695 | weak_factory_.GetWeakPtr()))); |
Alex Attar | 63ab3bd | 2023-07-11 19:31:44 | [diff] [blame] | 696 | } |
| 697 | |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 698 | bool BackgroundTracingManagerImpl::OnScenarioActive( |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 699 | TracingScenario* active_scenario) { |
| 700 | DCHECK_EQ(active_scenario_, nullptr); |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 701 | if (GetScenarioSavedCount(active_scenario->scenario_name()) >= |
| 702 | kMaxTracesPerScenario) { |
| 703 | return false; |
| 704 | } |
Etienne Pierre-doray | f704b17 | 2025-06-17 23:49:44 | [diff] [blame] | 705 | auto now = base::TimeTicks::Now(); |
| 706 | if (!delegate_->IsRecordingAllowed(active_scenario->privacy_filter_enabled(), |
| 707 | now)) { |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 708 | return false; |
| 709 | } |
Etienne Pierre-doray | f704b17 | 2025-06-17 23:49:44 | [diff] [blame] | 710 | scenario_start_time_ = now; |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 711 | active_scenario_ = active_scenario; |
Etienne Pierre-doray | 97f2a83 | 2024-04-05 15:55:55 | [diff] [blame] | 712 | base::UmaHistogramSparse( |
| 713 | "Tracing.Background.Scenario.Active", |
| 714 | variations::HashName(active_scenario->scenario_name())); |
Ali Hijazi | 133b2d9 | 2024-02-09 14:01:52 | [diff] [blame] | 715 | for (EnabledStateTestObserver* observer : background_tracing_observers_) { |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 716 | observer->OnScenarioActive(active_scenario_->scenario_name()); |
| 717 | } |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 718 | for (auto& scenario : enabled_scenarios_) { |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 719 | if (scenario.get() == active_scenario) { |
| 720 | continue; |
| 721 | } |
| 722 | scenario->Disable(); |
| 723 | } |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 724 | return true; |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 725 | } |
| 726 | |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 727 | bool BackgroundTracingManagerImpl::OnScenarioIdle( |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 728 | TracingScenario* idle_scenario) { |
| 729 | DCHECK_EQ(active_scenario_, idle_scenario); |
| 730 | active_scenario_ = nullptr; |
Etienne Pierre-doray | 97f2a83 | 2024-04-05 15:55:55 | [diff] [blame] | 731 | base::UmaHistogramSparse( |
| 732 | "Tracing.Background.Scenario.Idle", |
| 733 | variations::HashName(idle_scenario->scenario_name())); |
Ali Hijazi | 133b2d9 | 2024-02-09 14:01:52 | [diff] [blame] | 734 | for (EnabledStateTestObserver* observer : background_tracing_observers_) { |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 735 | observer->OnScenarioIdle(idle_scenario->scenario_name()); |
| 736 | } |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 737 | for (auto& scenario : enabled_scenarios_) { |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 738 | scenario->Enable(); |
| 739 | } |
Etienne Pierre-doray | f704b17 | 2025-06-17 23:49:44 | [diff] [blame] | 740 | return delegate_->IsRecordingAllowed(idle_scenario->privacy_filter_enabled(), |
| 741 | scenario_start_time_); |
Etienne Pierre-doray | 9c0b4c6 | 2024-11-08 14:00:16 | [diff] [blame] | 742 | } |
| 743 | |
Etienne Pierre-doray | 9653cf8 | 2025-02-07 17:08:50 | [diff] [blame] | 744 | void BackgroundTracingManagerImpl::OnScenarioError( |
| 745 | TracingScenario* scenario, |
| 746 | perfetto::TracingError error) { |
| 747 | base::UmaHistogramSparse("Tracing.Background.Scenario.Error", |
| 748 | variations::HashName(scenario->scenario_name())); |
| 749 | DLOG(ERROR) << "Background tracing error: " << error.message; |
| 750 | } |
| 751 | |
Etienne Pierre-doray | 9c0b4c6 | 2024-11-08 14:00:16 | [diff] [blame] | 752 | bool BackgroundTracingManagerImpl::OnScenarioCloned( |
| 753 | TracingScenario* cloned_scenario) { |
| 754 | DCHECK_EQ(active_scenario_, cloned_scenario); |
| 755 | base::UmaHistogramSparse( |
| 756 | "Tracing.Background.Scenario.Clone", |
| 757 | variations::HashName(cloned_scenario->scenario_name())); |
Etienne Pierre-doray | 3dc2c7dc | 2025-06-12 12:06:33 | [diff] [blame] | 758 | return delegate_->IsRecordingAllowed( |
Etienne Pierre-doray | f704b17 | 2025-06-17 23:49:44 | [diff] [blame] | 759 | cloned_scenario->privacy_filter_enabled(), scenario_start_time_); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 760 | } |
| 761 | |
| 762 | void BackgroundTracingManagerImpl::OnScenarioRecording( |
| 763 | TracingScenario* scenario) { |
| 764 | DCHECK_EQ(active_scenario_, scenario); |
Etienne Pierre-doray | 97f2a83 | 2024-04-05 15:55:55 | [diff] [blame] | 765 | base::UmaHistogramSparse("Tracing.Background.Scenario.Recording", |
| 766 | variations::HashName(scenario->scenario_name())); |
Etienne Pierre-doray | 67d8019 | 2024-11-14 21:52:47 | [diff] [blame] | 767 | BackgroundMetadataDataSource::EmitMetadata(scenario); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 768 | OnStartTracingDone(); |
| 769 | } |
| 770 | |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 771 | void BackgroundTracingManagerImpl::SaveTrace( |
| 772 | TracingScenario* scenario, |
Etienne Pierre-doray | 1444505 | 2023-12-08 17:46:22 | [diff] [blame] | 773 | base::Token trace_uuid, |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 774 | const BackgroundTracingRule* triggered_rule, |
| 775 | std::string&& trace_data) { |
Etienne Pierre-doray | 21315d3 | 2025-01-29 22:13:19 | [diff] [blame] | 776 | OnProtoDataComplete( |
| 777 | std::move(trace_data), scenario->scenario_name(), |
| 778 | triggered_rule->rule_name(), triggered_rule->triggered_value(), |
| 779 | scenario->privacy_filter_enabled(), scenario->is_local_scenario(), |
| 780 | /*force_upload=*/force_uploads_, trace_uuid); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 781 | } |
| 782 | |
oysteine | 5377260 | 2015-11-02 22:41:27 | [diff] [blame] | 783 | bool BackgroundTracingManagerImpl::HasActiveScenario() { |
Etienne Pierre-doray | aec3d57 | 2024-10-29 15:13:33 | [diff] [blame] | 784 | return active_scenario_ != nullptr; |
ssid | eb54962 | 2017-03-29 21:46:00 | [diff] [blame] | 785 | } |
| 786 | |
Siddhartha S | 52314f2 | 2019-03-27 20:07:16 | [diff] [blame] | 787 | bool BackgroundTracingManagerImpl::HasTraceToUpload() { |
Oystein Eftevaag | 3460b6b1 | 2019-05-15 16:40:15 | [diff] [blame] | 788 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 789 | if (!trace_report_to_upload_) { |
Siddhartha S | d1f4e97 | 2019-06-18 14:27:21 | [diff] [blame] | 790 | return false; |
| 791 | } |
Etienne Pierre-doray | 4234b21 | 2025-06-03 19:04:56 | [diff] [blame] | 792 | #if BUILDFLAG(IS_ANDROID) |
| 793 | // Send the logs only when the trace size is within limits. If the connection |
| 794 | // type changes and we have a bigger than expected trace, then the next time |
| 795 | // service asks us when wifi is available, the trace will be sent. |
| 796 | auto type = net::NetworkChangeNotifier::GetConnectionType(); |
| 797 | if (net::NetworkChangeNotifier::IsConnectionCellular(type) && |
| 798 | trace_report_to_upload_->total_size > upload_limit_network_kb_ * 1000) { |
| 799 | RecordMetric(Metrics::LARGE_UPLOAD_WAITING_TO_RETRY); |
| 800 | return false; |
Siddhartha S | d1f4e97 | 2019-06-18 14:27:21 | [diff] [blame] | 801 | } |
Etienne Pierre-doray | 4234b21 | 2025-06-03 19:04:56 | [diff] [blame] | 802 | #endif |
| 803 | return true; |
Siddhartha S | 52314f2 | 2019-03-27 20:07:16 | [diff] [blame] | 804 | } |
| 805 | |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 806 | void BackgroundTracingManagerImpl::GetTraceToUpload( |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 807 | base::OnceCallback<void(std::optional<std::string>, |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 808 | std::optional<std::string>, |
| 809 | base::OnceClosure)> receive_callback) { |
Oystein Eftevaag | 3460b6b1 | 2019-05-15 16:40:15 | [diff] [blame] | 810 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 811 | if (!trace_report_to_upload_) { |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 812 | std::move(receive_callback) |
| 813 | .Run(std::nullopt, std::nullopt, base::NullCallback()); |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 814 | return; |
| 815 | } |
Oystein Eftevaag | 3460b6b1 | 2019-05-15 16:40:15 | [diff] [blame] | 816 | |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 817 | DCHECK(trace_database_); |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 818 | BaseTraceReport trace_report = *std::move(trace_report_to_upload_); |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 819 | trace_report_to_upload_.reset(); |
| 820 | auto upload_complete_callback = base::BindPostTask( |
| 821 | database_task_runner_, |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 822 | base::BindOnce( |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 823 | OnUploadCompleteOnDatabaseTaskRunner, |
Etienne Pierre-doray | 3d11c68d | 2024-11-15 17:51:57 | [diff] [blame] | 824 | base::Unretained(trace_database_.get()), trace_report, |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 825 | base::BindOnce(&BackgroundTracingManagerImpl::OnFinalizeComplete, |
| 826 | weak_factory_.GetWeakPtr()))); |
Etienne Pierre-doray | 8563c89 | 2025-01-03 14:27:05 | [diff] [blame] | 827 | database_task_runner_->PostTask( |
| 828 | FROM_HERE, base::BindOnce(GetProtoValueOnDatabaseTaskRunner, |
| 829 | base::Unretained(trace_database_.get()), |
| 830 | trace_report, std::move(receive_callback), |
| 831 | std::move(upload_complete_callback))); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 832 | } |
| 833 | |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 834 | void BackgroundTracingManagerImpl::OnFinalizeComplete( |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 835 | std::optional<BaseTraceReport> trace_to_upload, |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 836 | bool success) { |
| 837 | trace_report_to_upload_ = std::move(trace_to_upload); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 838 | if (success) { |
| 839 | BackgroundTracingManagerImpl::RecordMetric(Metrics::UPLOAD_SUCCEEDED); |
| 840 | } else { |
| 841 | BackgroundTracingManagerImpl::RecordMetric(Metrics::UPLOAD_FAILED); |
Oystein Eftevaag | 3460b6b1 | 2019-05-15 16:40:15 | [diff] [blame] | 842 | } |
Siddhartha S | 52314f2 | 2019-03-27 20:07:16 | [diff] [blame] | 843 | } |
| 844 | |
Etienne Pierre-doray | b57b7394 | 2023-03-20 21:34:43 | [diff] [blame] | 845 | void BackgroundTracingManagerImpl::AddEnabledStateObserverForTesting( |
| 846 | BackgroundTracingManager::EnabledStateTestObserver* observer) { |
Oksana Zhuravlova | e0202790 | 2020-10-27 18:44:32 | [diff] [blame] | 847 | // Ensure that this code is called on the UI thread, except for |
| 848 | // tests where a UI thread might not have been initialized at this point. |
| 849 | DCHECK( |
| 850 | content::BrowserThread::CurrentlyOn(content::BrowserThread::UI) || |
| 851 | !content::BrowserThread::IsThreadInitialized(content::BrowserThread::UI)); |
Ehsan Chiniforooshan | a09fc88 | 2017-06-14 16:24:38 | [diff] [blame] | 852 | background_tracing_observers_.insert(observer); |
ssid | eb54962 | 2017-03-29 21:46:00 | [diff] [blame] | 853 | } |
| 854 | |
Etienne Pierre-doray | b57b7394 | 2023-03-20 21:34:43 | [diff] [blame] | 855 | void BackgroundTracingManagerImpl::RemoveEnabledStateObserverForTesting( |
| 856 | BackgroundTracingManager::EnabledStateTestObserver* observer) { |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 857 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Ehsan Chiniforooshan | a09fc88 | 2017-06-14 16:24:38 | [diff] [blame] | 858 | background_tracing_observers_.erase(observer); |
| 859 | } |
| 860 | |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 861 | void BackgroundTracingManagerImpl::AddAgent( |
| 862 | tracing::mojom::BackgroundTracingAgent* agent) { |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 863 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 864 | agents_.insert(agent); |
Ehsan Chiniforooshan | a09fc88 | 2017-06-14 16:24:38 | [diff] [blame] | 865 | |
Ali Hijazi | 133b2d9 | 2024-02-09 14:01:52 | [diff] [blame] | 866 | for (AgentObserver* observer : agent_observers_) { |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 867 | observer->OnAgentAdded(agent); |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 868 | } |
Ehsan Chiniforooshan | a09fc88 | 2017-06-14 16:24:38 | [diff] [blame] | 869 | } |
| 870 | |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 871 | void BackgroundTracingManagerImpl::RemoveAgent( |
| 872 | tracing::mojom::BackgroundTracingAgent* agent) { |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 873 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Ali Hijazi | 133b2d9 | 2024-02-09 14:01:52 | [diff] [blame] | 874 | for (AgentObserver* observer : agent_observers_) { |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 875 | observer->OnAgentRemoved(agent); |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 876 | } |
Ehsan Chiniforooshan | a09fc88 | 2017-06-14 16:24:38 | [diff] [blame] | 877 | |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 878 | agents_.erase(agent); |
Ehsan Chiniforooshan | a09fc88 | 2017-06-14 16:24:38 | [diff] [blame] | 879 | } |
| 880 | |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 881 | void BackgroundTracingManagerImpl::AddAgentObserver(AgentObserver* observer) { |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 882 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 883 | agent_observers_.insert(observer); |
Ehsan Chiniforooshan | a09fc88 | 2017-06-14 16:24:38 | [diff] [blame] | 884 | |
Darin Fisher | 53ceb1829 | 2019-06-21 22:26:15 | [diff] [blame] | 885 | MaybeConstructPendingAgents(); |
| 886 | |
Ali Hijazi | 133b2d9 | 2024-02-09 14:01:52 | [diff] [blame] | 887 | for (tracing::mojom::BackgroundTracingAgent* agent : agents_) { |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 888 | observer->OnAgentAdded(agent); |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 889 | } |
Ehsan Chiniforooshan | a09fc88 | 2017-06-14 16:24:38 | [diff] [blame] | 890 | } |
| 891 | |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 892 | void BackgroundTracingManagerImpl::RemoveAgentObserver( |
| 893 | AgentObserver* observer) { |
Ehsan Chiniforooshan | a09fc88 | 2017-06-14 16:24:38 | [diff] [blame] | 894 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 895 | agent_observers_.erase(observer); |
Ehsan Chiniforooshan | a09fc88 | 2017-06-14 16:24:38 | [diff] [blame] | 896 | |
Ali Hijazi | 133b2d9 | 2024-02-09 14:01:52 | [diff] [blame] | 897 | for (tracing::mojom::BackgroundTracingAgent* agent : agents_) { |
Darin Fisher | c23ee1a | 2019-06-05 23:26:30 | [diff] [blame] | 898 | observer->OnAgentRemoved(agent); |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 899 | } |
| 900 | } |
| 901 | |
oysteine | a7d2d84 | 2015-10-21 20:57:07 | [diff] [blame] | 902 | bool BackgroundTracingManagerImpl::IsTracingForTesting() { |
Etienne Pierre-doray | aec3d57 | 2024-10-29 15:13:33 | [diff] [blame] | 903 | return active_scenario_->current_state() == |
| 904 | TracingScenario::State::kRecording; |
oysteine | a7d2d84 | 2015-10-21 20:57:07 | [diff] [blame] | 905 | } |
| 906 | |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 907 | void BackgroundTracingManagerImpl::SaveTraceForTesting( |
| 908 | std::string&& serialized_trace, |
| 909 | const std::string& scenario_name, |
Alex Attar | f62d4e2 | 2023-09-26 16:49:43 | [diff] [blame] | 910 | const std::string& rule_name, |
| 911 | const base::Token& uuid) { |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 912 | InitializeTraceReportDatabase(true); |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 913 | OnProtoDataComplete(std::move(serialized_trace), scenario_name, rule_name, |
Etienne Pierre-doray | 21315d3 | 2025-01-29 22:13:19 | [diff] [blame] | 914 | /*rule_value=*/std::nullopt, |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 915 | /*privacy_filter_enabled*/ true, |
Etienne Pierre-doray | ffeda34 | 2024-11-05 21:47:47 | [diff] [blame] | 916 | /*is_local_scenario=*/false, |
Etienne Pierre-doray | 749ed49c | 2024-10-15 18:19:13 | [diff] [blame] | 917 | /*force_upload=*/force_uploads_, uuid); |
Oystein Eftevaag | 3460b6b1 | 2019-05-15 16:40:15 | [diff] [blame] | 918 | } |
| 919 | |
Etienne Pierre-doray | aec3d57 | 2024-10-29 15:13:33 | [diff] [blame] | 920 | void BackgroundTracingManagerImpl::SetUploadLimitsForTesting( |
| 921 | size_t upload_limit_kb, |
| 922 | size_t upload_limit_network_kb) { |
| 923 | upload_limit_kb_ = upload_limit_kb; |
| 924 | upload_limit_network_kb_ = upload_limit_network_kb; |
| 925 | } |
| 926 | |
Etienne Pierre-doray | 0af80e7 | 2024-06-28 18:25:29 | [diff] [blame] | 927 | void BackgroundTracingManagerImpl::SetPreferenceManagerForTesting( |
| 928 | std::unique_ptr<PreferenceManager> preferences) { |
| 929 | preferences_ = std::move(preferences); |
| 930 | } |
| 931 | |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 932 | size_t BackgroundTracingManagerImpl::GetScenarioSavedCount( |
| 933 | const std::string& scenario_name) { |
| 934 | auto it = scenario_saved_counts_.find(scenario_name); |
| 935 | if (it != scenario_saved_counts_.end()) { |
| 936 | return it->second; |
| 937 | } |
| 938 | return 0; |
| 939 | } |
| 940 | |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 941 | void BackgroundTracingManagerImpl::OnProtoDataComplete( |
| 942 | std::string&& serialized_trace, |
| 943 | const std::string& scenario_name, |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 944 | const std::string& rule_name, |
Etienne Pierre-doray | 21315d3 | 2025-01-29 22:13:19 | [diff] [blame] | 945 | std::optional<int32_t> rule_value, |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 946 | bool privacy_filter_enabled, |
Etienne Pierre-doray | ffeda34 | 2024-11-05 21:47:47 | [diff] [blame] | 947 | bool is_local_scenario, |
Etienne Pierre-doray | 749ed49c | 2024-10-15 18:19:13 | [diff] [blame] | 948 | bool force_upload, |
Alex Attar | f62d4e2 | 2023-09-26 16:49:43 | [diff] [blame] | 949 | const base::Token& uuid) { |
Oystein Eftevaag | 3460b6b1 | 2019-05-15 16:40:15 | [diff] [blame] | 950 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 951 | |
Ali Hijazi | 133b2d9 | 2024-02-09 14:01:52 | [diff] [blame] | 952 | for (EnabledStateTestObserver* observer : background_tracing_observers_) { |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 953 | observer->OnTraceReceived(serialized_trace); |
Oystein Eftevaag | 3460b6b1 | 2019-05-15 16:40:15 | [diff] [blame] | 954 | } |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 955 | if (!receive_callback_) { |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 956 | DCHECK(trace_database_); |
| 957 | |
Etienne Pierre-doray | 97f2a83 | 2024-04-05 15:55:55 | [diff] [blame] | 958 | base::UmaHistogramSparse("Tracing.Background.Scenario.SaveTrace", |
| 959 | variations::HashName(scenario_name)); |
Etienne Pierre-doray | 358170f | 2024-01-09 17:01:20 | [diff] [blame] | 960 | |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 961 | SkipUploadReason skip_reason = SkipUploadReason::kNoSkip; |
Etienne Pierre-doray | 8905505 | 2024-04-02 19:51:39 | [diff] [blame] | 962 | if (!privacy_filter_enabled) { |
Etienne Pierre-doray | 56a2a49b | 2023-09-13 18:16:45 | [diff] [blame] | 963 | skip_reason = SkipUploadReason::kNotAnonymized; |
Etienne Pierre-doray | ffeda34 | 2024-11-05 21:47:47 | [diff] [blame] | 964 | } else if (is_local_scenario) { |
| 965 | skip_reason = SkipUploadReason::kLocalScenario; |
Etienne Pierre-doray | 5b92814 | 2023-10-06 14:49:57 | [diff] [blame] | 966 | } else if (serialized_trace.size() > upload_limit_kb_ * 1024) { |
Alex Attar | b962f1a | 2023-09-06 17:12:23 | [diff] [blame] | 967 | skip_reason = SkipUploadReason::kSizeLimitExceeded; |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 968 | } |
Etienne Pierre-doray | 3dc2c7dc | 2025-06-12 12:06:33 | [diff] [blame] | 969 | bool should_save_trace = delegate_->ShouldSaveUnuploadedTrace(); |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 970 | if (skip_reason != SkipUploadReason::kNoSkip && !should_save_trace) { |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 971 | return; |
| 972 | } |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 973 | BackgroundTracingManagerImpl::RecordMetric(Metrics::FINALIZATION_STARTED); |
Etienne Pierre-doray | bd38b075 | 2023-09-05 22:42:46 | [diff] [blame] | 974 | |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 975 | BaseTraceReport base_report; |
Alex Attar | f62d4e2 | 2023-09-26 16:49:43 | [diff] [blame] | 976 | base_report.uuid = uuid; |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 977 | base_report.creation_time = base::Time::Now(); |
| 978 | base_report.scenario_name = scenario_name; |
| 979 | base_report.upload_rule_name = rule_name; |
Etienne Pierre-doray | 21315d3 | 2025-01-29 22:13:19 | [diff] [blame] | 980 | base_report.upload_rule_value = rule_value; |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 981 | base_report.total_size = serialized_trace.size(); |
| 982 | base_report.skip_reason = skip_reason; |
Etienne Pierre-doray | f5690182 | 2023-09-22 19:54:12 | [diff] [blame] | 983 | |
Etienne Pierre-doray | a9d9c41 | 2025-06-18 15:33:41 | [diff] [blame] | 984 | std::string serialized_system_profile = |
| 985 | delegate_->RecordSerializedSystemProfileMetrics(); |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 986 | |
| 987 | database_task_runner_->PostTask( |
| 988 | FROM_HERE, |
| 989 | base::BindOnce( |
| 990 | AddTraceOnDatabaseTaskRunner, |
| 991 | base::Unretained(trace_database_.get()), |
| 992 | std::move(serialized_trace), std::move(serialized_system_profile), |
Etienne Pierre-doray | 749ed49c | 2024-10-15 18:19:13 | [diff] [blame] | 993 | std::move(base_report), should_save_trace, force_upload, |
Etienne Pierre-doray | 98ecab4 | 2023-09-25 17:35:58 | [diff] [blame] | 994 | base::BindOnce(&BackgroundTracingManagerImpl::OnTraceSaved, |
| 995 | weak_factory_.GetWeakPtr(), scenario_name))); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 996 | } else { |
| 997 | BackgroundTracingManagerImpl::RecordMetric( |
| 998 | Metrics::FINALIZATION_STARTED_WITH_LOCAL_OUTPUT); |
| 999 | receive_callback_.Run( |
Etienne Pierre-doray | 34967f4 | 2024-04-17 16:42:54 | [diff] [blame] | 1000 | uuid.ToString() + ".perfetto.gz", std::move(serialized_trace), |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 1001 | base::BindOnce(&BackgroundTracingManagerImpl::OnFinalizeComplete, |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 1002 | weak_factory_.GetWeakPtr(), std::nullopt)); |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 1003 | } |
| 1004 | } |
| 1005 | |
Etienne Pierre-doray | 840a117 | 2024-03-18 22:57:00 | [diff] [blame] | 1006 | void BackgroundTracingManagerImpl::AddNamedTriggerObserver( |
Etienne Pierre-doray | b57b7394 | 2023-03-20 21:34:43 | [diff] [blame] | 1007 | const std::string& trigger_name, |
Etienne Pierre-doray | 840a117 | 2024-03-18 22:57:00 | [diff] [blame] | 1008 | BackgroundTracingRule* observer) { |
| 1009 | named_trigger_observers_[trigger_name].AddObserver(observer); |
| 1010 | } |
| 1011 | |
| 1012 | void BackgroundTracingManagerImpl::RemoveNamedTriggerObserver( |
| 1013 | const std::string& trigger_name, |
| 1014 | BackgroundTracingRule* observer) { |
| 1015 | named_trigger_observers_[trigger_name].RemoveObserver(observer); |
oysteine | a7d2d84 | 2015-10-21 20:57:07 | [diff] [blame] | 1016 | } |
| 1017 | |
Etienne Pierre-doray | 44477e15 | 2023-07-05 14:18:27 | [diff] [blame] | 1018 | bool BackgroundTracingManagerImpl::DoEmitNamedTrigger( |
Etienne Pierre-doray | 88cce9f | 2024-03-21 01:22:17 | [diff] [blame] | 1019 | const std::string& trigger_name, |
Etienne Pierre-doray | 226632b | 2025-02-11 20:51:21 | [diff] [blame] | 1020 | std::optional<int32_t> value, |
| 1021 | uint64_t flow_id) { |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 1022 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
simonhatch | 0b01619 | 2015-05-22 19:14:02 | [diff] [blame] | 1023 | |
Etienne Pierre-doray | 840a117 | 2024-03-18 22:57:00 | [diff] [blame] | 1024 | auto it = named_trigger_observers_.find(trigger_name); |
| 1025 | if (it == named_trigger_observers_.end()) { |
Etienne Pierre-doray | b57b7394 | 2023-03-20 21:34:43 | [diff] [blame] | 1026 | return false; |
| 1027 | } |
Etienne Pierre-doray | 840a117 | 2024-03-18 22:57:00 | [diff] [blame] | 1028 | for (BackgroundTracingRule& obs : it->second) { |
Etienne Pierre-doray | 226632b | 2025-02-11 20:51:21 | [diff] [blame] | 1029 | if (obs.OnRuleTriggered(value, flow_id)) { |
Etienne Pierre-doray | b5e78be | 2025-08-18 18:30:13 | [diff] [blame] | 1030 | TRACE_EVENT_INSTANT("tracing.background", "NamedTrigger", |
Etienne Pierre-doray | 226632b | 2025-02-11 20:51:21 | [diff] [blame] | 1031 | perfetto::Flow::Global(flow_id)); |
Etienne Pierre-doray | 840a117 | 2024-03-18 22:57:00 | [diff] [blame] | 1032 | return true; |
| 1033 | } |
| 1034 | } |
| 1035 | return false; |
simonhatch | 0b01619 | 2015-05-22 19:14:02 | [diff] [blame] | 1036 | } |
Oystein Eftevaag | ff99845 | 2019-05-13 20:47:06 | [diff] [blame] | 1037 | |
Etienne Pierre-doray | b57b7394 | 2023-03-20 21:34:43 | [diff] [blame] | 1038 | void BackgroundTracingManagerImpl::InvalidateTriggersCallbackForTesting() { |
Etienne Pierre-doray | 840a117 | 2024-03-18 22:57:00 | [diff] [blame] | 1039 | named_trigger_observers_.clear(); |
simonhatch | 0b01619 | 2015-05-22 19:14:02 | [diff] [blame] | 1040 | } |
| 1041 | |
Etienne Pierre-doray | e62bc2e | 2022-12-03 14:02:54 | [diff] [blame] | 1042 | void BackgroundTracingManagerImpl::OnStartTracingDone() { |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 1043 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Ali Hijazi | 133b2d9 | 2024-02-09 14:01:52 | [diff] [blame] | 1044 | for (EnabledStateTestObserver* observer : background_tracing_observers_) { |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 1045 | observer->OnTraceStarted(); |
Oystein Eftevaag | f80452b | 2019-03-19 16:30:22 | [diff] [blame] | 1046 | } |
Oystein Eftevaag | 7655e3cfd1 | 2018-12-19 18:20:19 | [diff] [blame] | 1047 | } |
oysteine | a7d2d84 | 2015-10-21 20:57:07 | [diff] [blame] | 1048 | |
Siddhartha S | 7d37b8d4 | 2019-06-07 23:53:12 | [diff] [blame] | 1049 | void BackgroundTracingManagerImpl::GenerateMetadataProto( |
ssid | f28a73d | 2019-08-21 20:09:26 | [diff] [blame] | 1050 | perfetto::protos::pbzero::ChromeMetadataPacket* metadata, |
| 1051 | bool privacy_filtering_enabled) { |
Siddhartha S | 7d37b8d4 | 2019-06-07 23:53:12 | [diff] [blame] | 1052 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Etienne Pierre-doray | aec3d57 | 2024-10-29 15:13:33 | [diff] [blame] | 1053 | if (active_scenario_) { |
Etienne Pierre-doray | b4d088dd | 2023-09-27 12:40:51 | [diff] [blame] | 1054 | active_scenario_->GenerateMetadataProto(metadata); |
Siddhartha S | 7d37b8d4 | 2019-06-07 23:53:12 | [diff] [blame] | 1055 | } |
| 1056 | } |
| 1057 | |
Oystein Eftevaag | 3460b6b1 | 2019-05-15 16:40:15 | [diff] [blame] | 1058 | void BackgroundTracingManagerImpl::AbortScenarioForTesting() { |
Etienne Pierre-doray | aec3d57 | 2024-10-29 15:13:33 | [diff] [blame] | 1059 | if (active_scenario_) { |
Etienne Pierre-doray | 825d20a1 | 2023-07-10 18:24:44 | [diff] [blame] | 1060 | active_scenario_->Abort(); |
Etienne Bergeron | 4d0ea2d | 2019-01-11 16:28:18 | [diff] [blame] | 1061 | } |
| 1062 | } |
| 1063 | |
Alex Attar | cc5eebb | 2023-08-11 16:35:55 | [diff] [blame] | 1064 | void BackgroundTracingManagerImpl::CleanDatabase() { |
| 1065 | DCHECK(trace_database_); |
| 1066 | |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 1067 | database_task_runner_->PostTaskAndReplyWithResult( |
Alex Attar | 9e640b2 | 2023-08-25 14:44:06 | [diff] [blame] | 1068 | FROM_HERE, |
| 1069 | base::BindOnce( |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 1070 | [](TraceReportDatabase* trace_database) { |
Etienne Pierre-doray | d05d46c | 2024-05-24 17:13:10 | [diff] [blame] | 1071 | // Trace payload is cleared on a more frequent basis. |
Etienne Pierre-doray | 064c0340 | 2024-08-22 20:17:17 | [diff] [blame] | 1072 | trace_database->DeleteOldTraceContent(kMaxTraceContent); |
Etienne Pierre-doray | d05d46c | 2024-05-24 17:13:10 | [diff] [blame] | 1073 | // The reports entries are kept (without the payload) for longer to |
| 1074 | // track upload quotas. |
| 1075 | trace_database->DeleteTraceReportsOlderThan(kTraceReportTimeToLive); |
Etienne Pierre-doray | f8f587c | 2024-12-06 19:39:00 | [diff] [blame] | 1076 | trace_database->DeleteUploadedTraceContentOlderThan( |
| 1077 | kUploadedTraceContentTimeToLive); |
Etienne Pierre-doray | d05d46c | 2024-05-24 17:13:10 | [diff] [blame] | 1078 | return trace_database->GetScenarioCountsSince( |
| 1079 | base::Time::Now() - kMaxTracesPerScenarioDuration); |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 1080 | }, |
| 1081 | base::Unretained(trace_database_.get())), |
| 1082 | base::BindOnce(&BackgroundTracingManagerImpl::OnTraceDatabaseUpdated, |
| 1083 | weak_factory_.GetWeakPtr())); |
Alex Attar | cc5eebb | 2023-08-11 16:35:55 | [diff] [blame] | 1084 | } |
| 1085 | |
| 1086 | void BackgroundTracingManagerImpl::DeleteTracesInDateRange(base::Time start, |
| 1087 | base::Time end) { |
Alex Attar | 9e640b2 | 2023-08-25 14:44:06 | [diff] [blame] | 1088 | // The trace report database needs to exist for clean up. Avoid creating or |
| 1089 | // initializing the trace report database to perform a database clean up. |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 1090 | std::optional<base::FilePath> database_dir; |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 1091 | if (!trace_database_) { |
| 1092 | database_dir = GetContentClient()->browser()->GetLocalTracesDirectory(); |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 1093 | if (database_dir.has_value()) { |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 1094 | return; |
| 1095 | } |
| 1096 | trace_database_ = {new TraceReportDatabase, |
| 1097 | base::OnTaskRunnerDeleter(database_task_runner_)}; |
Alex Attar | 9e640b2 | 2023-08-25 14:44:06 | [diff] [blame] | 1098 | } |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 1099 | auto on_database_updated = |
| 1100 | base::BindOnce(&BackgroundTracingManagerImpl::OnTraceDatabaseUpdated, |
| 1101 | weak_factory_.GetWeakPtr()); |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 1102 | database_task_runner_->PostTask( |
| 1103 | FROM_HERE, |
| 1104 | base::BindOnce( |
| 1105 | [](TraceReportDatabase* trace_database, |
Arthur Sonzogni | c686e8f | 2024-01-11 08:36:37 | [diff] [blame] | 1106 | std::optional<base::FilePath> database_dir, base::Time start, |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 1107 | base::Time end, |
| 1108 | base::OnceCallback<void(ScenarioCountMap)> on_database_updated) { |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 1109 | if (database_dir.has_value() && |
| 1110 | !trace_database->OpenDatabaseIfExists(database_dir.value())) { |
| 1111 | return; |
| 1112 | } |
| 1113 | if (!trace_database->is_initialized()) { |
| 1114 | return; |
| 1115 | } |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 1116 | if (trace_database->DeleteTracesInDateRange(start, end)) { |
| 1117 | GetUIThreadTaskRunner({})->PostTask( |
| 1118 | FROM_HERE, |
Etienne Pierre-doray | d05d46c | 2024-05-24 17:13:10 | [diff] [blame] | 1119 | base::BindOnce( |
| 1120 | std::move(on_database_updated), |
| 1121 | trace_database->GetScenarioCountsSince( |
| 1122 | base::Time::Now() - kMaxTracesPerScenarioDuration))); |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 1123 | } else { |
Etienne Pierre-doray | 6fe98bd | 2023-09-06 19:41:18 | [diff] [blame] | 1124 | RecordMetric(Metrics::DATABASE_CLEANUP_FAILED); |
| 1125 | } |
| 1126 | }, |
Etienne Pierre-doray | 3bb781fd8 | 2023-09-18 14:55:09 | [diff] [blame] | 1127 | base::Unretained(trace_database_.get()), database_dir, start, end, |
| 1128 | std::move(on_database_updated))); |
Alex Attar | cc5eebb | 2023-08-11 16:35:55 | [diff] [blame] | 1129 | } |
| 1130 | |
Darin Fisher | 53ceb1829 | 2019-06-21 22:26:15 | [diff] [blame] | 1131 | // static |
Wanchang Ryu | 342162a | 2020-02-27 19:31:25 | [diff] [blame] | 1132 | void BackgroundTracingManagerImpl::AddPendingAgent( |
| 1133 | int child_process_id, |
| 1134 | mojo::PendingRemote<tracing::mojom::BackgroundTracingAgentProvider> |
| 1135 | pending_provider) { |
Darin Fisher | 53ceb1829 | 2019-06-21 22:26:15 | [diff] [blame] | 1136 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Wanchang Ryu | 342162a | 2020-02-27 19:31:25 | [diff] [blame] | 1137 | // Delay agent initialization until we have an interested AgentObserver. |
| 1138 | // We set disconnect handler for cleanup when the tracing target is closed. |
| 1139 | mojo::Remote<tracing::mojom::BackgroundTracingAgentProvider> provider( |
| 1140 | std::move(pending_provider)); |
Darin Fisher | 53ceb1829 | 2019-06-21 22:26:15 | [diff] [blame] | 1141 | |
Wanchang Ryu | 342162a | 2020-02-27 19:31:25 | [diff] [blame] | 1142 | provider.set_disconnect_handler(base::BindOnce( |
| 1143 | &BackgroundTracingManagerImpl::ClearPendingAgent, child_process_id)); |
| 1144 | |
Oksana Zhuravlova | 872a5a6f | 2022-06-08 18:15:29 | [diff] [blame] | 1145 | GetInstance().pending_agents_[child_process_id] = std::move(provider); |
| 1146 | GetInstance().MaybeConstructPendingAgents(); |
Darin Fisher | 53ceb1829 | 2019-06-21 22:26:15 | [diff] [blame] | 1147 | } |
| 1148 | |
Wanchang Ryu | 342162a | 2020-02-27 19:31:25 | [diff] [blame] | 1149 | // static |
| 1150 | void BackgroundTracingManagerImpl::ClearPendingAgent(int child_process_id) { |
| 1151 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
Oksana Zhuravlova | 872a5a6f | 2022-06-08 18:15:29 | [diff] [blame] | 1152 | GetInstance().pending_agents_.erase(child_process_id); |
Wanchang Ryu | 342162a | 2020-02-27 19:31:25 | [diff] [blame] | 1153 | } |
| 1154 | |
Darin Fisher | 53ceb1829 | 2019-06-21 22:26:15 | [diff] [blame] | 1155 | void BackgroundTracingManagerImpl::MaybeConstructPendingAgents() { |
| 1156 | DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1157 | |
Etienne Pierre-doray | 0960910 | 2024-10-11 13:16:04 | [diff] [blame] | 1158 | if (agent_observers_.empty() && enabled_scenarios_.empty()) { |
Darin Fisher | 53ceb1829 | 2019-06-21 22:26:15 | [diff] [blame] | 1159 | return; |
Etienne Pierre-doray | 0960910 | 2024-10-11 13:16:04 | [diff] [blame] | 1160 | } |
Darin Fisher | 53ceb1829 | 2019-06-21 22:26:15 | [diff] [blame] | 1161 | |
Wanchang Ryu | 342162a | 2020-02-27 19:31:25 | [diff] [blame] | 1162 | for (auto& pending_agent : pending_agents_) { |
| 1163 | pending_agent.second.set_disconnect_handler(base::OnceClosure()); |
| 1164 | BackgroundTracingAgentClientImpl::Create(pending_agent.first, |
| 1165 | std::move(pending_agent.second)); |
| 1166 | } |
| 1167 | pending_agents_.clear(); |
Darin Fisher | 53ceb1829 | 2019-06-21 22:26:15 | [diff] [blame] | 1168 | } |
| 1169 | |
Etienne Bergeron | 32d2c24 | 2018-07-27 21:17:29 | [diff] [blame] | 1170 | } // namespace content |
Etienne Pierre-doray | 67d8019 | 2024-11-14 21:52:47 | [diff] [blame] | 1171 | |
| 1172 | PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS( |
| 1173 | COMPONENT_EXPORT(TRACING_CPP), |
| 1174 | content::BackgroundMetadataDataSource); |