• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // Copied from //external/perfetto/src/shared_lib/test/utils.cc
18 
19 #include "utils.h"
20 
21 #include "perfetto/public/abi/heap_buffer.h"
22 #include "perfetto/public/pb_msg.h"
23 #include "perfetto/public/pb_utils.h"
24 #include "perfetto/public/protos/config/data_source_config.pzc.h"
25 #include "perfetto/public/protos/config/trace_config.pzc.h"
26 #include "perfetto/public/protos/config/track_event/track_event_config.pzc.h"
27 #include "perfetto/public/tracing_session.h"
28 
29 #include "protos/perfetto/config/ftrace/ftrace_config.pb.h"
30 #include "protos/perfetto/config/track_event/track_event_config.pb.h"
31 #include "protos/perfetto/config/data_source_config.pb.h"
32 #include "protos/perfetto/config/trace_config.pb.h"
33 
34 namespace perfetto {
35 namespace shlib {
36 namespace test_utils {
Build()37 TracingSession TracingSession::Builder::Build() {
38   perfetto::protos::TraceConfig trace_config;
39   trace_config.add_buffers()->set_size_kb(1024);
40 
41   {
42     if (!atrace_categories_.empty()) {
43       auto* ftrace_ds_config = trace_config.add_data_sources()->mutable_config();
44       ftrace_ds_config->set_name("linux.ftrace");
45       ftrace_ds_config->set_target_buffer(0);
46 
47       auto* ftrace_config = ftrace_ds_config->mutable_ftrace_config();
48       ftrace_config->add_ftrace_events("ftrace/print");
49       for (const std::string& cat : atrace_categories_) {
50         ftrace_config->add_atrace_categories(cat);
51       }
52 
53       for (const std::string& cat : atrace_categories_prefer_sdk_) {
54         ftrace_config->add_atrace_categories_prefer_sdk(cat);
55       }
56     }
57   }
58 
59   {
60     if (!enabled_categories_.empty() || !disabled_categories_.empty()) {
61       auto* track_event_ds_config = trace_config.add_data_sources()->mutable_config();
62 
63       track_event_ds_config->set_name("track_event");
64       track_event_ds_config->set_target_buffer(0);
65 
66       auto* track_event_config = track_event_ds_config->mutable_track_event_config();
67 
68       for (const std::string& cat : enabled_categories_) {
69         track_event_config->add_enabled_categories(cat);
70       }
71 
72       for (const std::string& cat : disabled_categories_) {
73         track_event_config->add_disabled_categories(cat);
74       }
75     }
76   }
77 
78   std::string trace_config_string;
79   trace_config.SerializeToString(&trace_config_string);
80 
81   return TracingSession::FromBytes(trace_config_string.data(), trace_config_string.length());
82 }
83 
FromBytes(void * buf,size_t len)84 TracingSession TracingSession::FromBytes(void *buf, size_t len) {
85   struct PerfettoTracingSessionImpl* ts =
86       PerfettoTracingSessionCreate(PERFETTO_BACKEND_SYSTEM);
87 
88   PerfettoTracingSessionSetup(ts, buf, len);
89 
90   // Fails to start here
91   PerfettoTracingSessionStartBlocking(ts);
92 
93   return TracingSession::Adopt(ts);
94 }
95 
Adopt(struct PerfettoTracingSessionImpl * session)96 TracingSession TracingSession::Adopt(struct PerfettoTracingSessionImpl* session) {
97   TracingSession ret;
98   ret.session_ = session;
99   ret.stopped_ = std::make_unique<WaitableEvent>();
100   PerfettoTracingSessionSetStopCb(
101       ret.session_,
102       [](struct PerfettoTracingSessionImpl*, void* arg) {
103         static_cast<WaitableEvent*>(arg)->Notify();
104       },
105       ret.stopped_.get());
106   return ret;
107 }
108 
TracingSession(TracingSession && other)109 TracingSession::TracingSession(TracingSession&& other) noexcept {
110   session_ = other.session_;
111   other.session_ = nullptr;
112   stopped_ = std::move(other.stopped_);
113   other.stopped_ = nullptr;
114 }
115 
~TracingSession()116 TracingSession::~TracingSession() {
117   if (!session_) {
118     return;
119   }
120   if (!stopped_->IsNotified()) {
121     PerfettoTracingSessionStopBlocking(session_);
122     stopped_->WaitForNotification();
123   }
124   PerfettoTracingSessionDestroy(session_);
125 }
126 
FlushBlocking(uint32_t timeout_ms)127 bool TracingSession::FlushBlocking(uint32_t timeout_ms) {
128   WaitableEvent notification;
129   bool result;
130   auto* cb = new std::function<void(bool)>([&](bool success) {
131     result = success;
132     notification.Notify();
133   });
134   PerfettoTracingSessionFlushAsync(
135       session_, timeout_ms,
136       [](PerfettoTracingSessionImpl*, bool success, void* user_arg) {
137         auto* f = reinterpret_cast<std::function<void(bool)>*>(user_arg);
138         (*f)(success);
139         delete f;
140       },
141       cb);
142   notification.WaitForNotification();
143   return result;
144 }
145 
WaitForStopped()146 void TracingSession::WaitForStopped() {
147   stopped_->WaitForNotification();
148 }
149 
StopBlocking()150 void TracingSession::StopBlocking() {
151   PerfettoTracingSessionStopBlocking(session_);
152 }
153 
ReadBlocking()154 std::vector<uint8_t> TracingSession::ReadBlocking() {
155   std::vector<uint8_t> data;
156   PerfettoTracingSessionReadTraceBlocking(
157       session_,
158       [](struct PerfettoTracingSessionImpl*, const void* trace_data,
159          size_t size, bool, void* user_arg) {
160         auto& dst = *static_cast<std::vector<uint8_t>*>(user_arg);
161         auto* src = static_cast<const uint8_t*>(trace_data);
162         dst.insert(dst.end(), src, src + size);
163       },
164       &data);
165   return data;
166 }
167 
168 }  // namespace test_utils
169 }  // namespace shlib
170 }  // namespace perfetto
171