1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker *
4*6dbdd20aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker *
8*6dbdd20aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker *
10*6dbdd20aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker */
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard Worker #include "src/traced/service/builtin_producer.h"
18*6dbdd20aSAndroid Build Coastguard Worker
19*6dbdd20aSAndroid Build Coastguard Worker #include <sys/types.h>
20*6dbdd20aSAndroid Build Coastguard Worker
21*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/build_config.h"
22*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h"
23*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/proc_utils.h"
24*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/metatrace.h"
25*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/utils.h"
26*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/weak_ptr.h"
27*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/tracing/core/basic_types.h"
28*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/tracing/core/client_identity.h"
29*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/tracing/core/trace_writer.h"
30*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/tracing/core/tracing_service.h"
31*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/core/data_source_config.h"
32*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/core/data_source_descriptor.h"
33*6dbdd20aSAndroid Build Coastguard Worker #include "src/tracing/service/metatrace_writer.h"
34*6dbdd20aSAndroid Build Coastguard Worker
35*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.pbzero.h"
36*6dbdd20aSAndroid Build Coastguard Worker
37*6dbdd20aSAndroid Build Coastguard Worker // This translation unit is only ever used in Android in-tree builds.
38*6dbdd20aSAndroid Build Coastguard Worker // These producers are here to dynamically start heapprofd and other services
39*6dbdd20aSAndroid Build Coastguard Worker // via sysprops when a trace that requests them is active. That can only happen
40*6dbdd20aSAndroid Build Coastguard Worker // in in-tree builds of Android.
41*6dbdd20aSAndroid Build Coastguard Worker
42*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
43*6dbdd20aSAndroid Build Coastguard Worker #include <sys/system_properties.h>
44*6dbdd20aSAndroid Build Coastguard Worker #endif
45*6dbdd20aSAndroid Build Coastguard Worker
46*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
47*6dbdd20aSAndroid Build Coastguard Worker
48*6dbdd20aSAndroid Build Coastguard Worker namespace {
49*6dbdd20aSAndroid Build Coastguard Worker
50*6dbdd20aSAndroid Build Coastguard Worker constexpr char kHeapprofdDataSourceName[] = "android.heapprofd";
51*6dbdd20aSAndroid Build Coastguard Worker constexpr char kJavaHprofDataSourceName[] = "android.java_hprof";
52*6dbdd20aSAndroid Build Coastguard Worker constexpr char kJavaHprofOomDataSourceName[] = "android.java_hprof.oom";
53*6dbdd20aSAndroid Build Coastguard Worker constexpr char kTracedPerfDataSourceName[] = "linux.perf";
54*6dbdd20aSAndroid Build Coastguard Worker constexpr char kLazyHeapprofdPropertyName[] = "traced.lazy.heapprofd";
55*6dbdd20aSAndroid Build Coastguard Worker constexpr char kLazyTracedPerfPropertyName[] = "traced.lazy.traced_perf";
56*6dbdd20aSAndroid Build Coastguard Worker constexpr char kJavaHprofOomActivePropertyName[] =
57*6dbdd20aSAndroid Build Coastguard Worker "traced.oome_heap_session.count";
58*6dbdd20aSAndroid Build Coastguard Worker
59*6dbdd20aSAndroid Build Coastguard Worker constexpr char kAndroidSdkSyspropGuardDataSourceName[] =
60*6dbdd20aSAndroid Build Coastguard Worker "android.sdk_sysprop_guard";
61*6dbdd20aSAndroid Build Coastguard Worker constexpr char kPerfettoSdkSyspropGuardGenerationPropertyName[] =
62*6dbdd20aSAndroid Build Coastguard Worker "debug.tracing.ctl.perfetto.sdk_sysprop_guard_generation";
63*6dbdd20aSAndroid Build Coastguard Worker constexpr char kHwuiSkiaBroadTracingPropertyName[] =
64*6dbdd20aSAndroid Build Coastguard Worker "debug.tracing.ctl.hwui.skia_tracing_enabled";
65*6dbdd20aSAndroid Build Coastguard Worker constexpr char kHwuiSkiaUsePerfettoPropertyName[] =
66*6dbdd20aSAndroid Build Coastguard Worker "debug.tracing.ctl.hwui.skia_use_perfetto_track_events";
67*6dbdd20aSAndroid Build Coastguard Worker constexpr char kHwuiSkiaPropertyPackageSeparator[] = ".";
68*6dbdd20aSAndroid Build Coastguard Worker constexpr char kSurfaceFlingerSkiaBroadTracingPropertyName[] =
69*6dbdd20aSAndroid Build Coastguard Worker "debug.tracing.ctl.renderengine.skia_tracing_enabled";
70*6dbdd20aSAndroid Build Coastguard Worker constexpr char kSurfaceFlingerSkiaUsePerfettoPropertyName[] =
71*6dbdd20aSAndroid Build Coastguard Worker "debug.tracing.ctl.renderengine.skia_use_perfetto_track_events";
72*6dbdd20aSAndroid Build Coastguard Worker
73*6dbdd20aSAndroid Build Coastguard Worker } // namespace
74*6dbdd20aSAndroid Build Coastguard Worker
BuiltinProducer(base::TaskRunner * task_runner,uint32_t lazy_stop_delay_ms)75*6dbdd20aSAndroid Build Coastguard Worker BuiltinProducer::BuiltinProducer(base::TaskRunner* task_runner,
76*6dbdd20aSAndroid Build Coastguard Worker uint32_t lazy_stop_delay_ms)
77*6dbdd20aSAndroid Build Coastguard Worker : task_runner_(task_runner), weak_factory_(this) {
78*6dbdd20aSAndroid Build Coastguard Worker lazy_heapprofd_.stop_delay_ms = lazy_stop_delay_ms;
79*6dbdd20aSAndroid Build Coastguard Worker lazy_traced_perf_.stop_delay_ms = lazy_stop_delay_ms;
80*6dbdd20aSAndroid Build Coastguard Worker }
81*6dbdd20aSAndroid Build Coastguard Worker
~BuiltinProducer()82*6dbdd20aSAndroid Build Coastguard Worker BuiltinProducer::~BuiltinProducer() {
83*6dbdd20aSAndroid Build Coastguard Worker if (!lazy_heapprofd_.instance_ids.empty())
84*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(kLazyHeapprofdPropertyName, "");
85*6dbdd20aSAndroid Build Coastguard Worker if (!lazy_traced_perf_.instance_ids.empty())
86*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(kLazyTracedPerfPropertyName, "");
87*6dbdd20aSAndroid Build Coastguard Worker if (!java_hprof_oome_instances_.empty())
88*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(kJavaHprofOomActivePropertyName, "");
89*6dbdd20aSAndroid Build Coastguard Worker }
90*6dbdd20aSAndroid Build Coastguard Worker
ConnectInProcess(TracingService * svc)91*6dbdd20aSAndroid Build Coastguard Worker void BuiltinProducer::ConnectInProcess(TracingService* svc) {
92*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
93*6dbdd20aSAndroid Build Coastguard Worker // TODO(primiano): ConnectProducer should take a base::PlatformProcessId not
94*6dbdd20aSAndroid Build Coastguard Worker // pid_t, as they are different on Windows. But that is a larger refactoring
95*6dbdd20aSAndroid Build Coastguard Worker // and not worth given this is the only use case where it clashes.
96*6dbdd20aSAndroid Build Coastguard Worker const pid_t cur_proc_id = 0;
97*6dbdd20aSAndroid Build Coastguard Worker #else
98*6dbdd20aSAndroid Build Coastguard Worker const pid_t cur_proc_id = base::GetProcessId();
99*6dbdd20aSAndroid Build Coastguard Worker #endif
100*6dbdd20aSAndroid Build Coastguard Worker endpoint_ = svc->ConnectProducer(
101*6dbdd20aSAndroid Build Coastguard Worker this, ClientIdentity(base::GetCurrentUserId(), cur_proc_id), "traced",
102*6dbdd20aSAndroid Build Coastguard Worker /*shared_memory_size_hint_bytes=*/16 * 1024, /*in_process=*/true,
103*6dbdd20aSAndroid Build Coastguard Worker TracingService::ProducerSMBScrapingMode::kDisabled,
104*6dbdd20aSAndroid Build Coastguard Worker /*shared_memory_page_size_hint_bytes=*/4096);
105*6dbdd20aSAndroid Build Coastguard Worker }
106*6dbdd20aSAndroid Build Coastguard Worker
OnConnect()107*6dbdd20aSAndroid Build Coastguard Worker void BuiltinProducer::OnConnect() {
108*6dbdd20aSAndroid Build Coastguard Worker DataSourceDescriptor metatrace_dsd;
109*6dbdd20aSAndroid Build Coastguard Worker metatrace_dsd.set_name(MetatraceWriter::kDataSourceName);
110*6dbdd20aSAndroid Build Coastguard Worker metatrace_dsd.set_will_notify_on_stop(true);
111*6dbdd20aSAndroid Build Coastguard Worker endpoint_->RegisterDataSource(metatrace_dsd);
112*6dbdd20aSAndroid Build Coastguard Worker {
113*6dbdd20aSAndroid Build Coastguard Worker DataSourceDescriptor lazy_heapprofd_dsd;
114*6dbdd20aSAndroid Build Coastguard Worker lazy_heapprofd_dsd.set_name(kHeapprofdDataSourceName);
115*6dbdd20aSAndroid Build Coastguard Worker endpoint_->RegisterDataSource(lazy_heapprofd_dsd);
116*6dbdd20aSAndroid Build Coastguard Worker }
117*6dbdd20aSAndroid Build Coastguard Worker {
118*6dbdd20aSAndroid Build Coastguard Worker DataSourceDescriptor lazy_java_hprof_dsd;
119*6dbdd20aSAndroid Build Coastguard Worker lazy_java_hprof_dsd.set_name(kJavaHprofDataSourceName);
120*6dbdd20aSAndroid Build Coastguard Worker endpoint_->RegisterDataSource(lazy_java_hprof_dsd);
121*6dbdd20aSAndroid Build Coastguard Worker }
122*6dbdd20aSAndroid Build Coastguard Worker {
123*6dbdd20aSAndroid Build Coastguard Worker DataSourceDescriptor lazy_traced_perf_dsd;
124*6dbdd20aSAndroid Build Coastguard Worker lazy_traced_perf_dsd.set_name(kTracedPerfDataSourceName);
125*6dbdd20aSAndroid Build Coastguard Worker endpoint_->RegisterDataSource(lazy_traced_perf_dsd);
126*6dbdd20aSAndroid Build Coastguard Worker }
127*6dbdd20aSAndroid Build Coastguard Worker {
128*6dbdd20aSAndroid Build Coastguard Worker DataSourceDescriptor java_hprof_oome_dsd;
129*6dbdd20aSAndroid Build Coastguard Worker java_hprof_oome_dsd.set_name(kJavaHprofOomDataSourceName);
130*6dbdd20aSAndroid Build Coastguard Worker endpoint_->RegisterDataSource(java_hprof_oome_dsd);
131*6dbdd20aSAndroid Build Coastguard Worker }
132*6dbdd20aSAndroid Build Coastguard Worker {
133*6dbdd20aSAndroid Build Coastguard Worker DataSourceDescriptor track_event_dsd;
134*6dbdd20aSAndroid Build Coastguard Worker track_event_dsd.set_name(kAndroidSdkSyspropGuardDataSourceName);
135*6dbdd20aSAndroid Build Coastguard Worker endpoint_->RegisterDataSource(track_event_dsd);
136*6dbdd20aSAndroid Build Coastguard Worker }
137*6dbdd20aSAndroid Build Coastguard Worker }
138*6dbdd20aSAndroid Build Coastguard Worker
SetupDataSource(DataSourceInstanceID ds_id,const DataSourceConfig & ds_config)139*6dbdd20aSAndroid Build Coastguard Worker void BuiltinProducer::SetupDataSource(DataSourceInstanceID ds_id,
140*6dbdd20aSAndroid Build Coastguard Worker const DataSourceConfig& ds_config) {
141*6dbdd20aSAndroid Build Coastguard Worker if (ds_config.name() == kHeapprofdDataSourceName ||
142*6dbdd20aSAndroid Build Coastguard Worker ds_config.name() == kJavaHprofDataSourceName) {
143*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(kLazyHeapprofdPropertyName, "1");
144*6dbdd20aSAndroid Build Coastguard Worker lazy_heapprofd_.generation++;
145*6dbdd20aSAndroid Build Coastguard Worker lazy_heapprofd_.instance_ids.emplace(ds_id);
146*6dbdd20aSAndroid Build Coastguard Worker return;
147*6dbdd20aSAndroid Build Coastguard Worker }
148*6dbdd20aSAndroid Build Coastguard Worker
149*6dbdd20aSAndroid Build Coastguard Worker if (ds_config.name() == kTracedPerfDataSourceName) {
150*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(kLazyTracedPerfPropertyName, "1");
151*6dbdd20aSAndroid Build Coastguard Worker lazy_traced_perf_.generation++;
152*6dbdd20aSAndroid Build Coastguard Worker lazy_traced_perf_.instance_ids.emplace(ds_id);
153*6dbdd20aSAndroid Build Coastguard Worker return;
154*6dbdd20aSAndroid Build Coastguard Worker }
155*6dbdd20aSAndroid Build Coastguard Worker
156*6dbdd20aSAndroid Build Coastguard Worker if (ds_config.name() == kJavaHprofOomDataSourceName) {
157*6dbdd20aSAndroid Build Coastguard Worker java_hprof_oome_instances_.emplace(ds_id);
158*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(kJavaHprofOomActivePropertyName,
159*6dbdd20aSAndroid Build Coastguard Worker std::to_string(java_hprof_oome_instances_.size()));
160*6dbdd20aSAndroid Build Coastguard Worker return;
161*6dbdd20aSAndroid Build Coastguard Worker }
162*6dbdd20aSAndroid Build Coastguard Worker
163*6dbdd20aSAndroid Build Coastguard Worker // TODO(b/281329340): delete this when no longer needed.
164*6dbdd20aSAndroid Build Coastguard Worker if (ds_config.name() == kAndroidSdkSyspropGuardDataSourceName) {
165*6dbdd20aSAndroid Build Coastguard Worker protos::pbzero::AndroidSdkSyspropGuardConfig::Decoder sysprop_guard_config(
166*6dbdd20aSAndroid Build Coastguard Worker ds_config.android_sdk_sysprop_guard_config_raw());
167*6dbdd20aSAndroid Build Coastguard Worker std::vector<std::string> hwui_package_name_filter;
168*6dbdd20aSAndroid Build Coastguard Worker for (auto package = sysprop_guard_config.hwui_package_name_filter();
169*6dbdd20aSAndroid Build Coastguard Worker package; ++package) {
170*6dbdd20aSAndroid Build Coastguard Worker hwui_package_name_filter.emplace_back((*package).ToStdString());
171*6dbdd20aSAndroid Build Coastguard Worker }
172*6dbdd20aSAndroid Build Coastguard Worker
173*6dbdd20aSAndroid Build Coastguard Worker bool increase_generation = false;
174*6dbdd20aSAndroid Build Coastguard Worker
175*6dbdd20aSAndroid Build Coastguard Worker // SurfaceFlinger / RenderEngine
176*6dbdd20aSAndroid Build Coastguard Worker if (sysprop_guard_config.surfaceflinger_skia_track_events() &&
177*6dbdd20aSAndroid Build Coastguard Worker !android_sdk_sysprop_guard_state_.surfaceflinger_initialized) {
178*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(kSurfaceFlingerSkiaBroadTracingPropertyName, "true");
179*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(kSurfaceFlingerSkiaUsePerfettoPropertyName, "true");
180*6dbdd20aSAndroid Build Coastguard Worker android_sdk_sysprop_guard_state_.surfaceflinger_initialized = true;
181*6dbdd20aSAndroid Build Coastguard Worker increase_generation = true;
182*6dbdd20aSAndroid Build Coastguard Worker }
183*6dbdd20aSAndroid Build Coastguard Worker
184*6dbdd20aSAndroid Build Coastguard Worker // HWUI apps
185*6dbdd20aSAndroid Build Coastguard Worker if (sysprop_guard_config.hwui_skia_track_events()) {
186*6dbdd20aSAndroid Build Coastguard Worker if (hwui_package_name_filter.size() > 0) {
187*6dbdd20aSAndroid Build Coastguard Worker // Set per-app flags
188*6dbdd20aSAndroid Build Coastguard Worker for (std::string package : hwui_package_name_filter) {
189*6dbdd20aSAndroid Build Coastguard Worker if (android_sdk_sysprop_guard_state_.hwui_packages_initialized.count(
190*6dbdd20aSAndroid Build Coastguard Worker package) == 0) {
191*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(
192*6dbdd20aSAndroid Build Coastguard Worker kHwuiSkiaBroadTracingPropertyName +
193*6dbdd20aSAndroid Build Coastguard Worker (kHwuiSkiaPropertyPackageSeparator + package),
194*6dbdd20aSAndroid Build Coastguard Worker "true");
195*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(
196*6dbdd20aSAndroid Build Coastguard Worker kHwuiSkiaUsePerfettoPropertyName +
197*6dbdd20aSAndroid Build Coastguard Worker (kHwuiSkiaPropertyPackageSeparator + package),
198*6dbdd20aSAndroid Build Coastguard Worker "true");
199*6dbdd20aSAndroid Build Coastguard Worker android_sdk_sysprop_guard_state_.hwui_packages_initialized.insert(
200*6dbdd20aSAndroid Build Coastguard Worker package);
201*6dbdd20aSAndroid Build Coastguard Worker increase_generation = true;
202*6dbdd20aSAndroid Build Coastguard Worker }
203*6dbdd20aSAndroid Build Coastguard Worker }
204*6dbdd20aSAndroid Build Coastguard Worker } else if (!android_sdk_sysprop_guard_state_.hwui_globally_initialized) {
205*6dbdd20aSAndroid Build Coastguard Worker // Set global flag
206*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(kHwuiSkiaBroadTracingPropertyName, "true");
207*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(kHwuiSkiaUsePerfettoPropertyName, "true");
208*6dbdd20aSAndroid Build Coastguard Worker android_sdk_sysprop_guard_state_.hwui_globally_initialized = true;
209*6dbdd20aSAndroid Build Coastguard Worker increase_generation = true;
210*6dbdd20aSAndroid Build Coastguard Worker }
211*6dbdd20aSAndroid Build Coastguard Worker }
212*6dbdd20aSAndroid Build Coastguard Worker
213*6dbdd20aSAndroid Build Coastguard Worker if (increase_generation) {
214*6dbdd20aSAndroid Build Coastguard Worker android_sdk_sysprop_guard_state_.generation++;
215*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(
216*6dbdd20aSAndroid Build Coastguard Worker kPerfettoSdkSyspropGuardGenerationPropertyName,
217*6dbdd20aSAndroid Build Coastguard Worker std::to_string(android_sdk_sysprop_guard_state_.generation));
218*6dbdd20aSAndroid Build Coastguard Worker }
219*6dbdd20aSAndroid Build Coastguard Worker
220*6dbdd20aSAndroid Build Coastguard Worker return;
221*6dbdd20aSAndroid Build Coastguard Worker }
222*6dbdd20aSAndroid Build Coastguard Worker }
223*6dbdd20aSAndroid Build Coastguard Worker
StartDataSource(DataSourceInstanceID ds_id,const DataSourceConfig & ds_config)224*6dbdd20aSAndroid Build Coastguard Worker void BuiltinProducer::StartDataSource(DataSourceInstanceID ds_id,
225*6dbdd20aSAndroid Build Coastguard Worker const DataSourceConfig& ds_config) {
226*6dbdd20aSAndroid Build Coastguard Worker // We slightly rely on the fact that since this producer is in-process for
227*6dbdd20aSAndroid Build Coastguard Worker // enabling metatrace early (relative to producers that are notified via IPC).
228*6dbdd20aSAndroid Build Coastguard Worker if (ds_config.name() == MetatraceWriter::kDataSourceName) {
229*6dbdd20aSAndroid Build Coastguard Worker auto writer = endpoint_->CreateTraceWriter(
230*6dbdd20aSAndroid Build Coastguard Worker static_cast<BufferID>(ds_config.target_buffer()));
231*6dbdd20aSAndroid Build Coastguard Worker
232*6dbdd20aSAndroid Build Coastguard Worker auto it_and_inserted = metatrace_.writers.emplace(
233*6dbdd20aSAndroid Build Coastguard Worker std::piecewise_construct, std::make_tuple(ds_id), std::make_tuple());
234*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DCHECK(it_and_inserted.second);
235*6dbdd20aSAndroid Build Coastguard Worker // Note: only the first concurrent writer will actually be active.
236*6dbdd20aSAndroid Build Coastguard Worker metatrace_.writers[ds_id].Enable(task_runner_, std::move(writer),
237*6dbdd20aSAndroid Build Coastguard Worker metatrace::TAG_ANY);
238*6dbdd20aSAndroid Build Coastguard Worker }
239*6dbdd20aSAndroid Build Coastguard Worker }
240*6dbdd20aSAndroid Build Coastguard Worker
StopDataSource(DataSourceInstanceID ds_id)241*6dbdd20aSAndroid Build Coastguard Worker void BuiltinProducer::StopDataSource(DataSourceInstanceID ds_id) {
242*6dbdd20aSAndroid Build Coastguard Worker auto meta_it = metatrace_.writers.find(ds_id);
243*6dbdd20aSAndroid Build Coastguard Worker if (meta_it != metatrace_.writers.end()) {
244*6dbdd20aSAndroid Build Coastguard Worker // Synchronously re-flush the metatrace writer to record more of the
245*6dbdd20aSAndroid Build Coastguard Worker // teardown interactions, then ack the stop.
246*6dbdd20aSAndroid Build Coastguard Worker meta_it->second.WriteAllAndFlushTraceWriter([] {});
247*6dbdd20aSAndroid Build Coastguard Worker metatrace_.writers.erase(meta_it);
248*6dbdd20aSAndroid Build Coastguard Worker endpoint_->NotifyDataSourceStopped(ds_id);
249*6dbdd20aSAndroid Build Coastguard Worker return;
250*6dbdd20aSAndroid Build Coastguard Worker }
251*6dbdd20aSAndroid Build Coastguard Worker
252*6dbdd20aSAndroid Build Coastguard Worker MaybeInitiateLazyStop(ds_id, &lazy_heapprofd_, kLazyHeapprofdPropertyName);
253*6dbdd20aSAndroid Build Coastguard Worker MaybeInitiateLazyStop(ds_id, &lazy_traced_perf_, kLazyTracedPerfPropertyName);
254*6dbdd20aSAndroid Build Coastguard Worker
255*6dbdd20aSAndroid Build Coastguard Worker auto oome_it = java_hprof_oome_instances_.find(ds_id);
256*6dbdd20aSAndroid Build Coastguard Worker if (oome_it != java_hprof_oome_instances_.end()) {
257*6dbdd20aSAndroid Build Coastguard Worker java_hprof_oome_instances_.erase(oome_it);
258*6dbdd20aSAndroid Build Coastguard Worker SetAndroidProperty(kJavaHprofOomActivePropertyName,
259*6dbdd20aSAndroid Build Coastguard Worker std::to_string(java_hprof_oome_instances_.size()));
260*6dbdd20aSAndroid Build Coastguard Worker }
261*6dbdd20aSAndroid Build Coastguard Worker }
262*6dbdd20aSAndroid Build Coastguard Worker
MaybeInitiateLazyStop(DataSourceInstanceID ds_id,LazyAndroidDaemonState * lazy_state,const char * prop_name)263*6dbdd20aSAndroid Build Coastguard Worker void BuiltinProducer::MaybeInitiateLazyStop(DataSourceInstanceID ds_id,
264*6dbdd20aSAndroid Build Coastguard Worker LazyAndroidDaemonState* lazy_state,
265*6dbdd20aSAndroid Build Coastguard Worker const char* prop_name) {
266*6dbdd20aSAndroid Build Coastguard Worker auto lazy_it = lazy_state->instance_ids.find(ds_id);
267*6dbdd20aSAndroid Build Coastguard Worker if (lazy_it != lazy_state->instance_ids.end()) {
268*6dbdd20aSAndroid Build Coastguard Worker lazy_state->instance_ids.erase(lazy_it);
269*6dbdd20aSAndroid Build Coastguard Worker
270*6dbdd20aSAndroid Build Coastguard Worker // if no more sessions - stop daemon after a delay
271*6dbdd20aSAndroid Build Coastguard Worker if (lazy_state->instance_ids.empty()) {
272*6dbdd20aSAndroid Build Coastguard Worker uint64_t cur_generation = lazy_state->generation;
273*6dbdd20aSAndroid Build Coastguard Worker auto weak_this = weak_factory_.GetWeakPtr();
274*6dbdd20aSAndroid Build Coastguard Worker task_runner_->PostDelayedTask(
275*6dbdd20aSAndroid Build Coastguard Worker [weak_this, cur_generation, lazy_state, prop_name] {
276*6dbdd20aSAndroid Build Coastguard Worker if (!weak_this)
277*6dbdd20aSAndroid Build Coastguard Worker return;
278*6dbdd20aSAndroid Build Coastguard Worker // |lazy_state| should be valid if the |weak_this| is still valid
279*6dbdd20aSAndroid Build Coastguard Worker if (lazy_state->generation == cur_generation)
280*6dbdd20aSAndroid Build Coastguard Worker weak_this->SetAndroidProperty(prop_name, "");
281*6dbdd20aSAndroid Build Coastguard Worker },
282*6dbdd20aSAndroid Build Coastguard Worker lazy_state->stop_delay_ms);
283*6dbdd20aSAndroid Build Coastguard Worker }
284*6dbdd20aSAndroid Build Coastguard Worker }
285*6dbdd20aSAndroid Build Coastguard Worker }
286*6dbdd20aSAndroid Build Coastguard Worker
Flush(FlushRequestID flush_id,const DataSourceInstanceID * ds_ids,size_t num_ds_ids,FlushFlags)287*6dbdd20aSAndroid Build Coastguard Worker void BuiltinProducer::Flush(FlushRequestID flush_id,
288*6dbdd20aSAndroid Build Coastguard Worker const DataSourceInstanceID* ds_ids,
289*6dbdd20aSAndroid Build Coastguard Worker size_t num_ds_ids,
290*6dbdd20aSAndroid Build Coastguard Worker FlushFlags) {
291*6dbdd20aSAndroid Build Coastguard Worker for (size_t i = 0; i < num_ds_ids; i++) {
292*6dbdd20aSAndroid Build Coastguard Worker auto meta_it = metatrace_.writers.find(ds_ids[i]);
293*6dbdd20aSAndroid Build Coastguard Worker if (meta_it != metatrace_.writers.end()) {
294*6dbdd20aSAndroid Build Coastguard Worker meta_it->second.WriteAllAndFlushTraceWriter([] {});
295*6dbdd20aSAndroid Build Coastguard Worker }
296*6dbdd20aSAndroid Build Coastguard Worker // nothing to be done for lazy sources
297*6dbdd20aSAndroid Build Coastguard Worker }
298*6dbdd20aSAndroid Build Coastguard Worker endpoint_->NotifyFlushComplete(flush_id);
299*6dbdd20aSAndroid Build Coastguard Worker }
300*6dbdd20aSAndroid Build Coastguard Worker
SetAndroidProperty(const std::string & name,const std::string & value)301*6dbdd20aSAndroid Build Coastguard Worker bool BuiltinProducer::SetAndroidProperty(const std::string& name,
302*6dbdd20aSAndroid Build Coastguard Worker const std::string& value) {
303*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
304*6dbdd20aSAndroid Build Coastguard Worker return __system_property_set(name.c_str(), value.c_str()) == 0;
305*6dbdd20aSAndroid Build Coastguard Worker #else
306*6dbdd20aSAndroid Build Coastguard Worker // Allow this to be mocked out for tests on other platforms.
307*6dbdd20aSAndroid Build Coastguard Worker base::ignore_result(name);
308*6dbdd20aSAndroid Build Coastguard Worker base::ignore_result(value);
309*6dbdd20aSAndroid Build Coastguard Worker return true;
310*6dbdd20aSAndroid Build Coastguard Worker #endif
311*6dbdd20aSAndroid Build Coastguard Worker }
312*6dbdd20aSAndroid Build Coastguard Worker
313*6dbdd20aSAndroid Build Coastguard Worker } // namespace perfetto
314