xref: /aosp_15_r20/external/perfetto/src/tracing/test/api_integrationtest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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 <fcntl.h>
18*6dbdd20aSAndroid Build Coastguard Worker 
19*6dbdd20aSAndroid Build Coastguard Worker #include <chrono>
20*6dbdd20aSAndroid Build Coastguard Worker #include <condition_variable>
21*6dbdd20aSAndroid Build Coastguard Worker #include <fstream>
22*6dbdd20aSAndroid Build Coastguard Worker #include <functional>
23*6dbdd20aSAndroid Build Coastguard Worker #include <list>
24*6dbdd20aSAndroid Build Coastguard Worker #include <mutex>
25*6dbdd20aSAndroid Build Coastguard Worker #include <regex>
26*6dbdd20aSAndroid Build Coastguard Worker #include <string_view>
27*6dbdd20aSAndroid Build Coastguard Worker #include <thread>
28*6dbdd20aSAndroid Build Coastguard Worker #include <unordered_set>
29*6dbdd20aSAndroid Build Coastguard Worker #include <vector>
30*6dbdd20aSAndroid Build Coastguard Worker 
31*6dbdd20aSAndroid Build Coastguard Worker // We also want to test legacy trace events.
32*6dbdd20aSAndroid Build Coastguard Worker #define PERFETTO_ENABLE_LEGACY_TRACE_EVENTS 1
33*6dbdd20aSAndroid Build Coastguard Worker 
34*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing.h"
35*6dbdd20aSAndroid Build Coastguard Worker #include "test/gtest_and_gmock.h"
36*6dbdd20aSAndroid Build Coastguard Worker #include "test/integrationtest_initializer.h"
37*6dbdd20aSAndroid Build Coastguard Worker 
38*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
39*6dbdd20aSAndroid Build Coastguard Worker #include <Windows.h>  // For CreateFile().
40*6dbdd20aSAndroid Build Coastguard Worker #else
41*6dbdd20aSAndroid Build Coastguard Worker #include <sys/socket.h>
42*6dbdd20aSAndroid Build Coastguard Worker #include <sys/types.h>
43*6dbdd20aSAndroid Build Coastguard Worker #include <sys/un.h>
44*6dbdd20aSAndroid Build Coastguard Worker #endif
45*6dbdd20aSAndroid Build Coastguard Worker 
46*6dbdd20aSAndroid Build Coastguard Worker // Deliberately not pulling any non-public perfetto header to spot accidental
47*6dbdd20aSAndroid Build Coastguard Worker // header public -> non-public dependency while building this file.
48*6dbdd20aSAndroid Build Coastguard Worker 
49*6dbdd20aSAndroid Build Coastguard Worker // These two are the only headers allowed here, see comments in
50*6dbdd20aSAndroid Build Coastguard Worker // api_test_support.h.
51*6dbdd20aSAndroid Build Coastguard Worker #include "src/tracing/test/api_test_support.h"
52*6dbdd20aSAndroid Build Coastguard Worker #include "src/tracing/test/tracing_module.h"
53*6dbdd20aSAndroid Build Coastguard Worker 
54*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/time.h"
55*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/protozero/scattered_heap_buffer.h"
56*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/core/data_source_descriptor.h"
57*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/core/trace_config.h"
58*6dbdd20aSAndroid Build Coastguard Worker 
59*6dbdd20aSAndroid Build Coastguard Worker // xxx.pbzero.h includes are for the writing path (the code that pretends to be
60*6dbdd20aSAndroid Build Coastguard Worker // production code).
61*6dbdd20aSAndroid Build Coastguard Worker // yyy.gen.h includes are for the test readback path (the code in the test that
62*6dbdd20aSAndroid Build Coastguard Worker // checks that the results are valid).
63*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/common/builtin_clock.pbzero.h"
64*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/common/interceptor_descriptor.gen.h"
65*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/common/trace_stats.gen.h"
66*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/common/tracing_service_state.gen.h"
67*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/common/track_event_descriptor.gen.h"
68*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/common/track_event_descriptor.pbzero.h"
69*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/config/interceptor_config.gen.h"
70*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/config/track_event/track_event_config.gen.h"
71*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/clock_snapshot.gen.h"
72*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
73*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/gpu/gpu_render_stage_event.gen.h"
74*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.h"
75*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/interned_data/interned_data.gen.h"
76*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
77*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/profiling/profile_common.gen.h"
78*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/test_event.gen.h"
79*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/test_event.pbzero.h"
80*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/test_extensions.pbzero.h"
81*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/trace.gen.h"
82*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/trace.pbzero.h"
83*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/trace_packet.gen.h"
84*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/trace_packet.pbzero.h"
85*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/trace_packet_defaults.gen.h"
86*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
87*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.h"
88*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
89*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
90*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
91*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/log_message.gen.h"
92*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/log_message.pbzero.h"
93*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
94*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
95*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/source_location.gen.h"
96*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/source_location.pbzero.h"
97*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
98*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
99*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/track_descriptor.gen.h"
100*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/track_event/track_event.gen.h"
101*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/trace/trigger.gen.h"
102*6dbdd20aSAndroid Build Coastguard Worker 
103*6dbdd20aSAndroid Build Coastguard Worker // Events in categories starting with "dynamic" will use dynamic category
104*6dbdd20aSAndroid Build Coastguard Worker // lookup.
105*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DEFINE_TEST_CATEGORY_PREFIXES("dynamic");
106*6dbdd20aSAndroid Build Coastguard Worker 
107*6dbdd20aSAndroid Build Coastguard Worker // Trace categories used in the tests.
108*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DEFINE_CATEGORIES(
109*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Category("test")
110*6dbdd20aSAndroid Build Coastguard Worker         .SetDescription("This is a test category")
111*6dbdd20aSAndroid Build Coastguard Worker         .SetTags("tag"),
112*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Category("foo"),
113*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Category("bar"),
114*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Category("cat").SetTags("slow"),
115*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Category("cat.verbose").SetTags("debug"),
116*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Category("cat-with-dashes"),
117*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Category::Group("foo,bar"),
118*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Category::Group("baz,bar,quux"),
119*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Category::Group("red,green,blue,foo"),
120*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Category::Group("red,green,blue,yellow"),
121*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Category(TRACE_DISABLED_BY_DEFAULT("cat")));
122*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_TRACK_EVENT_STATIC_STORAGE();
123*6dbdd20aSAndroid Build Coastguard Worker 
124*6dbdd20aSAndroid Build Coastguard Worker // Test declaring an extra set of categories in a namespace in addition to the
125*6dbdd20aSAndroid Build Coastguard Worker // default one.
126*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE(other_ns,
127*6dbdd20aSAndroid Build Coastguard Worker                                         perfetto::Category("other_ns"));
128*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE(other_ns);
129*6dbdd20aSAndroid Build Coastguard Worker 
130*6dbdd20aSAndroid Build Coastguard Worker // For testing interning of complex objects.
131*6dbdd20aSAndroid Build Coastguard Worker using SourceLocation = std::tuple<const char* /* file_name */,
132*6dbdd20aSAndroid Build Coastguard Worker                                   const char* /* function_name */,
133*6dbdd20aSAndroid Build Coastguard Worker                                   uint32_t /* line_number */>;
134*6dbdd20aSAndroid Build Coastguard Worker 
135*6dbdd20aSAndroid Build Coastguard Worker template <>
136*6dbdd20aSAndroid Build Coastguard Worker struct std::hash<SourceLocation> {
operator ()std::hash137*6dbdd20aSAndroid Build Coastguard Worker   size_t operator()(const SourceLocation& value) const {
138*6dbdd20aSAndroid Build Coastguard Worker     auto hasher = hash<size_t>();
139*6dbdd20aSAndroid Build Coastguard Worker     return hasher(reinterpret_cast<size_t>(get<0>(value))) ^
140*6dbdd20aSAndroid Build Coastguard Worker            hasher(reinterpret_cast<size_t>(get<1>(value))) ^
141*6dbdd20aSAndroid Build Coastguard Worker            hasher(get<2>(value));
142*6dbdd20aSAndroid Build Coastguard Worker   }
143*6dbdd20aSAndroid Build Coastguard Worker };
144*6dbdd20aSAndroid Build Coastguard Worker 
WriteFile(const std::string & file_name,const char * content,size_t len)145*6dbdd20aSAndroid Build Coastguard Worker static void WriteFile(const std::string& file_name,
146*6dbdd20aSAndroid Build Coastguard Worker                       const char* content,
147*6dbdd20aSAndroid Build Coastguard Worker                       size_t len) {
148*6dbdd20aSAndroid Build Coastguard Worker   std::ofstream output;
149*6dbdd20aSAndroid Build Coastguard Worker   output.open(file_name.c_str(), std::ios::out | std::ios::binary);
150*6dbdd20aSAndroid Build Coastguard Worker   output.write(content, static_cast<std::streamsize>(len));
151*6dbdd20aSAndroid Build Coastguard Worker   output.close();
152*6dbdd20aSAndroid Build Coastguard Worker }
153*6dbdd20aSAndroid Build Coastguard Worker 
154*6dbdd20aSAndroid Build Coastguard Worker // Unused in merged code, but very handy for debugging when trace generated in
155*6dbdd20aSAndroid Build Coastguard Worker // a test needs to be exported, to understand it further with other tools.
WriteFile(const std::string & file_name,const std::vector<char> & data)156*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_UNUSED static void WriteFile(const std::string& file_name,
157*6dbdd20aSAndroid Build Coastguard Worker                                       const std::vector<char>& data) {
158*6dbdd20aSAndroid Build Coastguard Worker   return WriteFile(file_name, data.data(), data.size());
159*6dbdd20aSAndroid Build Coastguard Worker }
160*6dbdd20aSAndroid Build Coastguard Worker 
161*6dbdd20aSAndroid Build Coastguard Worker // Returns true if the |key| is present in |container|.
162*6dbdd20aSAndroid Build Coastguard Worker template <typename ContainerType, class KeyType>
ContainsKey(const ContainerType & container,const KeyType & key)163*6dbdd20aSAndroid Build Coastguard Worker bool ContainsKey(const ContainerType& container, const KeyType& key) {
164*6dbdd20aSAndroid Build Coastguard Worker   return container.find(key) != container.end();
165*6dbdd20aSAndroid Build Coastguard Worker }
166*6dbdd20aSAndroid Build Coastguard Worker 
167*6dbdd20aSAndroid Build Coastguard Worker // Represents an opaque (from Perfetto's point of view) thread identifier (e.g.,
168*6dbdd20aSAndroid Build Coastguard Worker // base::PlatformThreadId in Chromium).
169*6dbdd20aSAndroid Build Coastguard Worker struct MyThreadId {
MyThreadIdMyThreadId170*6dbdd20aSAndroid Build Coastguard Worker   explicit MyThreadId(int tid_) : tid(tid_) {}
171*6dbdd20aSAndroid Build Coastguard Worker 
172*6dbdd20aSAndroid Build Coastguard Worker   const int tid = 0;
173*6dbdd20aSAndroid Build Coastguard Worker };
174*6dbdd20aSAndroid Build Coastguard Worker 
175*6dbdd20aSAndroid Build Coastguard Worker // Represents an opaque timestamp (e.g., base::TimeTicks in Chromium).
176*6dbdd20aSAndroid Build Coastguard Worker class MyTimestamp {
177*6dbdd20aSAndroid Build Coastguard Worker  public:
MyTimestamp(uint64_t ts_)178*6dbdd20aSAndroid Build Coastguard Worker   explicit MyTimestamp(uint64_t ts_) : ts(ts_) {}
179*6dbdd20aSAndroid Build Coastguard Worker 
180*6dbdd20aSAndroid Build Coastguard Worker   const uint64_t ts;
181*6dbdd20aSAndroid Build Coastguard Worker };
182*6dbdd20aSAndroid Build Coastguard Worker 
183*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
184*6dbdd20aSAndroid Build Coastguard Worker namespace legacy {
185*6dbdd20aSAndroid Build Coastguard Worker 
186*6dbdd20aSAndroid Build Coastguard Worker template <>
ConvertThreadId(const MyThreadId & thread)187*6dbdd20aSAndroid Build Coastguard Worker ThreadTrack ConvertThreadId(const MyThreadId& thread) {
188*6dbdd20aSAndroid Build Coastguard Worker   return perfetto::ThreadTrack::ForThread(
189*6dbdd20aSAndroid Build Coastguard Worker       static_cast<base::PlatformThreadId>(thread.tid));
190*6dbdd20aSAndroid Build Coastguard Worker }
191*6dbdd20aSAndroid Build Coastguard Worker 
192*6dbdd20aSAndroid Build Coastguard Worker }  // namespace legacy
193*6dbdd20aSAndroid Build Coastguard Worker 
194*6dbdd20aSAndroid Build Coastguard Worker template <>
195*6dbdd20aSAndroid Build Coastguard Worker struct TraceTimestampTraits<MyTimestamp> {
ConvertTimestampToTraceTimeNsperfetto::TraceTimestampTraits196*6dbdd20aSAndroid Build Coastguard Worker   static TraceTimestamp ConvertTimestampToTraceTimeNs(
197*6dbdd20aSAndroid Build Coastguard Worker       const MyTimestamp& timestamp) {
198*6dbdd20aSAndroid Build Coastguard Worker     return {static_cast<uint32_t>(TrackEvent::GetTraceClockId()), timestamp.ts};
199*6dbdd20aSAndroid Build Coastguard Worker   }
200*6dbdd20aSAndroid Build Coastguard Worker };
201*6dbdd20aSAndroid Build Coastguard Worker 
202*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
203*6dbdd20aSAndroid Build Coastguard Worker 
204*6dbdd20aSAndroid Build Coastguard Worker namespace {
205*6dbdd20aSAndroid Build Coastguard Worker 
206*6dbdd20aSAndroid Build Coastguard Worker using perfetto::TracingInitArgs;
207*6dbdd20aSAndroid Build Coastguard Worker using perfetto::internal::TrackEventIncrementalState;
208*6dbdd20aSAndroid Build Coastguard Worker using perfetto::internal::TrackEventInternal;
209*6dbdd20aSAndroid Build Coastguard Worker using ::perfetto::test::DataSourceInternalForTest;
210*6dbdd20aSAndroid Build Coastguard Worker using ::testing::_;
211*6dbdd20aSAndroid Build Coastguard Worker using ::testing::AllOf;
212*6dbdd20aSAndroid Build Coastguard Worker using ::testing::ContainerEq;
213*6dbdd20aSAndroid Build Coastguard Worker using ::testing::Contains;
214*6dbdd20aSAndroid Build Coastguard Worker using ::testing::Each;
215*6dbdd20aSAndroid Build Coastguard Worker using ::testing::ElementsAre;
216*6dbdd20aSAndroid Build Coastguard Worker using ::testing::HasSubstr;
217*6dbdd20aSAndroid Build Coastguard Worker using ::testing::Invoke;
218*6dbdd20aSAndroid Build Coastguard Worker using ::testing::InvokeWithoutArgs;
219*6dbdd20aSAndroid Build Coastguard Worker using ::testing::IsEmpty;
220*6dbdd20aSAndroid Build Coastguard Worker using ::testing::MockFunction;
221*6dbdd20aSAndroid Build Coastguard Worker using ::testing::NiceMock;
222*6dbdd20aSAndroid Build Coastguard Worker using ::testing::Not;
223*6dbdd20aSAndroid Build Coastguard Worker using ::testing::Property;
224*6dbdd20aSAndroid Build Coastguard Worker using ::testing::StrEq;
225*6dbdd20aSAndroid Build Coastguard Worker 
226*6dbdd20aSAndroid Build Coastguard Worker // ------------------------------
227*6dbdd20aSAndroid Build Coastguard Worker // Declarations of helper classes
228*6dbdd20aSAndroid Build Coastguard Worker // ------------------------------
229*6dbdd20aSAndroid Build Coastguard Worker 
230*6dbdd20aSAndroid Build Coastguard Worker class WaitableTestEvent {
231*6dbdd20aSAndroid Build Coastguard Worker  public:
notified()232*6dbdd20aSAndroid Build Coastguard Worker   bool notified() {
233*6dbdd20aSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mutex_);
234*6dbdd20aSAndroid Build Coastguard Worker     return notified_;
235*6dbdd20aSAndroid Build Coastguard Worker   }
236*6dbdd20aSAndroid Build Coastguard Worker 
Wait()237*6dbdd20aSAndroid Build Coastguard Worker   void Wait() {
238*6dbdd20aSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mutex_);
239*6dbdd20aSAndroid Build Coastguard Worker     // TSAN gets confused by wait_for, which we would use here in a perfect
240*6dbdd20aSAndroid Build Coastguard Worker     // world.
241*6dbdd20aSAndroid Build Coastguard Worker     cv_.wait(lock, [this] { return notified_; });
242*6dbdd20aSAndroid Build Coastguard Worker   }
243*6dbdd20aSAndroid Build Coastguard Worker 
Notify()244*6dbdd20aSAndroid Build Coastguard Worker   void Notify() {
245*6dbdd20aSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mutex_);
246*6dbdd20aSAndroid Build Coastguard Worker     notified_ = true;
247*6dbdd20aSAndroid Build Coastguard Worker     cv_.notify_one();
248*6dbdd20aSAndroid Build Coastguard Worker   }
249*6dbdd20aSAndroid Build Coastguard Worker 
Reset()250*6dbdd20aSAndroid Build Coastguard Worker   void Reset() {
251*6dbdd20aSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(mutex_);
252*6dbdd20aSAndroid Build Coastguard Worker     notified_ = false;
253*6dbdd20aSAndroid Build Coastguard Worker     cv_.notify_one();
254*6dbdd20aSAndroid Build Coastguard Worker   }
255*6dbdd20aSAndroid Build Coastguard Worker 
256*6dbdd20aSAndroid Build Coastguard Worker  private:
257*6dbdd20aSAndroid Build Coastguard Worker   std::mutex mutex_;
258*6dbdd20aSAndroid Build Coastguard Worker   std::condition_variable cv_;
259*6dbdd20aSAndroid Build Coastguard Worker   bool notified_ = false;
260*6dbdd20aSAndroid Build Coastguard Worker };
261*6dbdd20aSAndroid Build Coastguard Worker 
262*6dbdd20aSAndroid Build Coastguard Worker template <typename Func>
263*6dbdd20aSAndroid Build Coastguard Worker class Cleanup {
264*6dbdd20aSAndroid Build Coastguard Worker  public:
Cleanup(Func f)265*6dbdd20aSAndroid Build Coastguard Worker   explicit Cleanup(Func f) : f_(std::move(f)) {}
~Cleanup()266*6dbdd20aSAndroid Build Coastguard Worker   ~Cleanup() { f_(); }
267*6dbdd20aSAndroid Build Coastguard Worker   Cleanup(Cleanup&&) noexcept = default;
268*6dbdd20aSAndroid Build Coastguard Worker   Cleanup& operator=(Cleanup&&) noexcept = default;
269*6dbdd20aSAndroid Build Coastguard Worker   Cleanup(const Cleanup&) = delete;
270*6dbdd20aSAndroid Build Coastguard Worker   Cleanup& operator=(const Cleanup&) = delete;
271*6dbdd20aSAndroid Build Coastguard Worker 
272*6dbdd20aSAndroid Build Coastguard Worker  private:
273*6dbdd20aSAndroid Build Coastguard Worker   Func f_;
274*6dbdd20aSAndroid Build Coastguard Worker };
275*6dbdd20aSAndroid Build Coastguard Worker template <typename Func>
MakeCleanup(Func f)276*6dbdd20aSAndroid Build Coastguard Worker Cleanup<Func> MakeCleanup(Func f) {
277*6dbdd20aSAndroid Build Coastguard Worker   return Cleanup<Func>(std::move(f));
278*6dbdd20aSAndroid Build Coastguard Worker }
279*6dbdd20aSAndroid Build Coastguard Worker 
280*6dbdd20aSAndroid Build Coastguard Worker class CustomDataSource : public perfetto::DataSource<CustomDataSource> {};
281*6dbdd20aSAndroid Build Coastguard Worker 
282*6dbdd20aSAndroid Build Coastguard Worker class MockDataSource;
283*6dbdd20aSAndroid Build Coastguard Worker 
284*6dbdd20aSAndroid Build Coastguard Worker // We can't easily use gmock here because instances of data sources are lazily
285*6dbdd20aSAndroid Build Coastguard Worker // created by the service and are not owned by the test fixture.
286*6dbdd20aSAndroid Build Coastguard Worker struct TestDataSourceHandle {
287*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent on_create;
288*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent on_setup;
289*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent on_start;
290*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent on_stop;
291*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent on_flush;
292*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource* instance;
293*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceConfig config;
294*6dbdd20aSAndroid Build Coastguard Worker   bool is_datasource_started = false;
295*6dbdd20aSAndroid Build Coastguard Worker   bool handle_stop_asynchronously = false;
296*6dbdd20aSAndroid Build Coastguard Worker   bool handle_flush_asynchronously = false;
297*6dbdd20aSAndroid Build Coastguard Worker   std::function<void()> on_start_callback;
298*6dbdd20aSAndroid Build Coastguard Worker   std::function<void()> on_stop_callback;
299*6dbdd20aSAndroid Build Coastguard Worker   std::function<void(perfetto::FlushFlags)> on_flush_callback;
300*6dbdd20aSAndroid Build Coastguard Worker   std::function<void()> async_stop_closure;
301*6dbdd20aSAndroid Build Coastguard Worker   std::function<void()> async_flush_closure;
302*6dbdd20aSAndroid Build Coastguard Worker };
303*6dbdd20aSAndroid Build Coastguard Worker 
304*6dbdd20aSAndroid Build Coastguard Worker class MockDataSource : public perfetto::DataSource<MockDataSource> {
305*6dbdd20aSAndroid Build Coastguard Worker  public:
306*6dbdd20aSAndroid Build Coastguard Worker   void OnSetup(const SetupArgs&) override;
307*6dbdd20aSAndroid Build Coastguard Worker   void OnStart(const StartArgs&) override;
308*6dbdd20aSAndroid Build Coastguard Worker   void OnStop(const StopArgs&) override;
309*6dbdd20aSAndroid Build Coastguard Worker   void OnFlush(const FlushArgs&) override;
310*6dbdd20aSAndroid Build Coastguard Worker   TestDataSourceHandle* handle_ = nullptr;
311*6dbdd20aSAndroid Build Coastguard Worker };
312*6dbdd20aSAndroid Build Coastguard Worker 
313*6dbdd20aSAndroid Build Coastguard Worker constexpr int kTestDataSourceArg = 123;
314*6dbdd20aSAndroid Build Coastguard Worker 
315*6dbdd20aSAndroid Build Coastguard Worker class MockDataSource2 : public perfetto::DataSource<MockDataSource2> {
316*6dbdd20aSAndroid Build Coastguard Worker  public:
MockDataSource2(int arg)317*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource2(int arg) { EXPECT_EQ(arg, kTestDataSourceArg); }
OnSetup(const SetupArgs &)318*6dbdd20aSAndroid Build Coastguard Worker   void OnSetup(const SetupArgs&) override {}
OnStart(const StartArgs &)319*6dbdd20aSAndroid Build Coastguard Worker   void OnStart(const StartArgs&) override {}
OnStop(const StopArgs &)320*6dbdd20aSAndroid Build Coastguard Worker   void OnStop(const StopArgs&) override {}
321*6dbdd20aSAndroid Build Coastguard Worker };
322*6dbdd20aSAndroid Build Coastguard Worker 
323*6dbdd20aSAndroid Build Coastguard Worker // Used to verify that track event data sources in different namespaces register
324*6dbdd20aSAndroid Build Coastguard Worker // themselves correctly in the muxer.
325*6dbdd20aSAndroid Build Coastguard Worker class MockTracingMuxer : public perfetto::internal::TracingMuxer {
326*6dbdd20aSAndroid Build Coastguard Worker  public:
327*6dbdd20aSAndroid Build Coastguard Worker   struct DataSource {
328*6dbdd20aSAndroid Build Coastguard Worker     perfetto::DataSourceDescriptor dsd;
329*6dbdd20aSAndroid Build Coastguard Worker     perfetto::internal::DataSourceStaticState* static_state;
330*6dbdd20aSAndroid Build Coastguard Worker   };
331*6dbdd20aSAndroid Build Coastguard Worker 
MockTracingMuxer()332*6dbdd20aSAndroid Build Coastguard Worker   MockTracingMuxer() : TracingMuxer(nullptr), prev_instance_(instance_) {
333*6dbdd20aSAndroid Build Coastguard Worker     instance_ = this;
334*6dbdd20aSAndroid Build Coastguard Worker   }
~MockTracingMuxer()335*6dbdd20aSAndroid Build Coastguard Worker   ~MockTracingMuxer() override { instance_ = prev_instance_; }
336*6dbdd20aSAndroid Build Coastguard Worker 
RegisterDataSource(const perfetto::DataSourceDescriptor & dsd,DataSourceFactory,perfetto::internal::DataSourceParams,bool,perfetto::internal::DataSourceStaticState * static_state)337*6dbdd20aSAndroid Build Coastguard Worker   bool RegisterDataSource(
338*6dbdd20aSAndroid Build Coastguard Worker       const perfetto::DataSourceDescriptor& dsd,
339*6dbdd20aSAndroid Build Coastguard Worker       DataSourceFactory,
340*6dbdd20aSAndroid Build Coastguard Worker       perfetto::internal::DataSourceParams,
341*6dbdd20aSAndroid Build Coastguard Worker       bool,
342*6dbdd20aSAndroid Build Coastguard Worker       perfetto::internal::DataSourceStaticState* static_state) override {
343*6dbdd20aSAndroid Build Coastguard Worker     data_sources.emplace_back(DataSource{dsd, static_state});
344*6dbdd20aSAndroid Build Coastguard Worker     return true;
345*6dbdd20aSAndroid Build Coastguard Worker   }
346*6dbdd20aSAndroid Build Coastguard Worker 
UpdateDataSourceDescriptor(const perfetto::DataSourceDescriptor & dsd,const perfetto::internal::DataSourceStaticState * static_state)347*6dbdd20aSAndroid Build Coastguard Worker   void UpdateDataSourceDescriptor(
348*6dbdd20aSAndroid Build Coastguard Worker       const perfetto::DataSourceDescriptor& dsd,
349*6dbdd20aSAndroid Build Coastguard Worker       const perfetto::internal::DataSourceStaticState* static_state) override {
350*6dbdd20aSAndroid Build Coastguard Worker     for (auto& rds : data_sources) {
351*6dbdd20aSAndroid Build Coastguard Worker       if (rds.static_state == static_state) {
352*6dbdd20aSAndroid Build Coastguard Worker         rds.dsd = dsd;
353*6dbdd20aSAndroid Build Coastguard Worker         return;
354*6dbdd20aSAndroid Build Coastguard Worker       }
355*6dbdd20aSAndroid Build Coastguard Worker     }
356*6dbdd20aSAndroid Build Coastguard Worker   }
357*6dbdd20aSAndroid Build Coastguard Worker 
CreateTraceWriter(perfetto::internal::DataSourceStaticState *,uint32_t,perfetto::internal::DataSourceState *,perfetto::BufferExhaustedPolicy)358*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<perfetto::TraceWriterBase> CreateTraceWriter(
359*6dbdd20aSAndroid Build Coastguard Worker       perfetto::internal::DataSourceStaticState*,
360*6dbdd20aSAndroid Build Coastguard Worker       uint32_t,
361*6dbdd20aSAndroid Build Coastguard Worker       perfetto::internal::DataSourceState*,
362*6dbdd20aSAndroid Build Coastguard Worker       perfetto::BufferExhaustedPolicy) override {
363*6dbdd20aSAndroid Build Coastguard Worker     return nullptr;
364*6dbdd20aSAndroid Build Coastguard Worker   }
365*6dbdd20aSAndroid Build Coastguard Worker 
DestroyStoppedTraceWritersForCurrentThread()366*6dbdd20aSAndroid Build Coastguard Worker   void DestroyStoppedTraceWritersForCurrentThread() override {}
RegisterInterceptor(const perfetto::InterceptorDescriptor &,InterceptorFactory,perfetto::InterceptorBase::TLSFactory,perfetto::InterceptorBase::TracePacketCallback)367*6dbdd20aSAndroid Build Coastguard Worker   void RegisterInterceptor(
368*6dbdd20aSAndroid Build Coastguard Worker       const perfetto::InterceptorDescriptor&,
369*6dbdd20aSAndroid Build Coastguard Worker       InterceptorFactory,
370*6dbdd20aSAndroid Build Coastguard Worker       perfetto::InterceptorBase::TLSFactory,
371*6dbdd20aSAndroid Build Coastguard Worker       perfetto::InterceptorBase::TracePacketCallback) override {}
372*6dbdd20aSAndroid Build Coastguard Worker 
ActivateTriggers(const std::vector<std::string> &,uint32_t)373*6dbdd20aSAndroid Build Coastguard Worker   void ActivateTriggers(const std::vector<std::string>&, uint32_t) override {}
374*6dbdd20aSAndroid Build Coastguard Worker 
375*6dbdd20aSAndroid Build Coastguard Worker   std::vector<DataSource> data_sources;
376*6dbdd20aSAndroid Build Coastguard Worker 
377*6dbdd20aSAndroid Build Coastguard Worker  private:
378*6dbdd20aSAndroid Build Coastguard Worker   TracingMuxer* prev_instance_;
379*6dbdd20aSAndroid Build Coastguard Worker };
380*6dbdd20aSAndroid Build Coastguard Worker 
381*6dbdd20aSAndroid Build Coastguard Worker struct TestIncrementalState {
TestIncrementalState__anonfc73210d0111::TestIncrementalState382*6dbdd20aSAndroid Build Coastguard Worker   TestIncrementalState() { constructed = true; }
383*6dbdd20aSAndroid Build Coastguard Worker   // Note: a virtual destructor is not required for incremental state.
~TestIncrementalState__anonfc73210d0111::TestIncrementalState384*6dbdd20aSAndroid Build Coastguard Worker   ~TestIncrementalState() { destroyed = true; }
385*6dbdd20aSAndroid Build Coastguard Worker 
386*6dbdd20aSAndroid Build Coastguard Worker   int count = 100;
387*6dbdd20aSAndroid Build Coastguard Worker   bool flag = false;
388*6dbdd20aSAndroid Build Coastguard Worker   static bool constructed;
389*6dbdd20aSAndroid Build Coastguard Worker   static bool destroyed;
390*6dbdd20aSAndroid Build Coastguard Worker };
391*6dbdd20aSAndroid Build Coastguard Worker 
392*6dbdd20aSAndroid Build Coastguard Worker bool TestIncrementalState::constructed;
393*6dbdd20aSAndroid Build Coastguard Worker bool TestIncrementalState::destroyed;
394*6dbdd20aSAndroid Build Coastguard Worker 
395*6dbdd20aSAndroid Build Coastguard Worker struct TestIncrementalDataSourceTraits
396*6dbdd20aSAndroid Build Coastguard Worker     : public perfetto::DefaultDataSourceTraits {
397*6dbdd20aSAndroid Build Coastguard Worker   using IncrementalStateType = TestIncrementalState;
398*6dbdd20aSAndroid Build Coastguard Worker   using CustomTlsState = void;
399*6dbdd20aSAndroid Build Coastguard Worker };
400*6dbdd20aSAndroid Build Coastguard Worker 
401*6dbdd20aSAndroid Build Coastguard Worker class TestIncrementalDataSource
402*6dbdd20aSAndroid Build Coastguard Worker     : public perfetto::DataSource<TestIncrementalDataSource,
403*6dbdd20aSAndroid Build Coastguard Worker                                   TestIncrementalDataSourceTraits> {
404*6dbdd20aSAndroid Build Coastguard Worker  public:
OnSetup(const SetupArgs &)405*6dbdd20aSAndroid Build Coastguard Worker   void OnSetup(const SetupArgs&) override {}
OnStart(const StartArgs &)406*6dbdd20aSAndroid Build Coastguard Worker   void OnStart(const StartArgs&) override {}
OnStop(const StopArgs &)407*6dbdd20aSAndroid Build Coastguard Worker   void OnStop(const StopArgs&) override {}
WillClearIncrementalState(const ClearIncrementalStateArgs & args)408*6dbdd20aSAndroid Build Coastguard Worker   void WillClearIncrementalState(
409*6dbdd20aSAndroid Build Coastguard Worker       const ClearIncrementalStateArgs& args) override {
410*6dbdd20aSAndroid Build Coastguard Worker     if (will_clear_incremental_state) {
411*6dbdd20aSAndroid Build Coastguard Worker       (*will_clear_incremental_state)(args);
412*6dbdd20aSAndroid Build Coastguard Worker     }
413*6dbdd20aSAndroid Build Coastguard Worker   }
414*6dbdd20aSAndroid Build Coastguard Worker 
SetWillClearIncrementalStateCallback(std::function<void (const DataSourceBase::ClearIncrementalStateArgs &)> cb)415*6dbdd20aSAndroid Build Coastguard Worker   static void SetWillClearIncrementalStateCallback(
416*6dbdd20aSAndroid Build Coastguard Worker       std::function<void(const DataSourceBase::ClearIncrementalStateArgs&)> cb) {
417*6dbdd20aSAndroid Build Coastguard Worker     if (will_clear_incremental_state) {
418*6dbdd20aSAndroid Build Coastguard Worker       delete will_clear_incremental_state;
419*6dbdd20aSAndroid Build Coastguard Worker       will_clear_incremental_state = nullptr;
420*6dbdd20aSAndroid Build Coastguard Worker     }
421*6dbdd20aSAndroid Build Coastguard Worker     if (cb) {
422*6dbdd20aSAndroid Build Coastguard Worker       will_clear_incremental_state = new decltype(cb)(cb);
423*6dbdd20aSAndroid Build Coastguard Worker     }
424*6dbdd20aSAndroid Build Coastguard Worker   }
425*6dbdd20aSAndroid Build Coastguard Worker 
426*6dbdd20aSAndroid Build Coastguard Worker  private:
427*6dbdd20aSAndroid Build Coastguard Worker   static std::function<void(const ClearIncrementalStateArgs&)>*
428*6dbdd20aSAndroid Build Coastguard Worker       will_clear_incremental_state;
429*6dbdd20aSAndroid Build Coastguard Worker };
430*6dbdd20aSAndroid Build Coastguard Worker 
431*6dbdd20aSAndroid Build Coastguard Worker std::function<void(const perfetto::DataSourceBase::ClearIncrementalStateArgs&)>*
432*6dbdd20aSAndroid Build Coastguard Worker     TestIncrementalDataSource::will_clear_incremental_state;
433*6dbdd20aSAndroid Build Coastguard Worker 
434*6dbdd20aSAndroid Build Coastguard Worker // A convenience wrapper around TracingSession that allows to do block on
435*6dbdd20aSAndroid Build Coastguard Worker //
436*6dbdd20aSAndroid Build Coastguard Worker struct TestTracingSessionHandle {
get__anonfc73210d0111::TestTracingSessionHandle437*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TracingSession* get() { return session.get(); }
438*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<perfetto::TracingSession> session;
439*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent on_stop;
440*6dbdd20aSAndroid Build Coastguard Worker };
441*6dbdd20aSAndroid Build Coastguard Worker 
442*6dbdd20aSAndroid Build Coastguard Worker class MyDebugAnnotation : public perfetto::DebugAnnotation {
443*6dbdd20aSAndroid Build Coastguard Worker  public:
444*6dbdd20aSAndroid Build Coastguard Worker   ~MyDebugAnnotation() override = default;
445*6dbdd20aSAndroid Build Coastguard Worker 
Add(perfetto::protos::pbzero::DebugAnnotation * annotation) const446*6dbdd20aSAndroid Build Coastguard Worker   void Add(
447*6dbdd20aSAndroid Build Coastguard Worker       perfetto::protos::pbzero::DebugAnnotation* annotation) const override {
448*6dbdd20aSAndroid Build Coastguard Worker     annotation->set_legacy_json_value(R"({"key": 123})");
449*6dbdd20aSAndroid Build Coastguard Worker   }
450*6dbdd20aSAndroid Build Coastguard Worker };
451*6dbdd20aSAndroid Build Coastguard Worker 
452*6dbdd20aSAndroid Build Coastguard Worker class TestTracingPolicy : public perfetto::TracingPolicy {
453*6dbdd20aSAndroid Build Coastguard Worker  public:
ShouldAllowConsumerSession(const ShouldAllowConsumerSessionArgs & args)454*6dbdd20aSAndroid Build Coastguard Worker   void ShouldAllowConsumerSession(
455*6dbdd20aSAndroid Build Coastguard Worker       const ShouldAllowConsumerSessionArgs& args) override {
456*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_NE(args.backend_type, perfetto::BackendType::kUnspecifiedBackend);
457*6dbdd20aSAndroid Build Coastguard Worker     args.result_callback(should_allow_consumer_connection);
458*6dbdd20aSAndroid Build Coastguard Worker   }
459*6dbdd20aSAndroid Build Coastguard Worker 
460*6dbdd20aSAndroid Build Coastguard Worker   bool should_allow_consumer_connection = true;
461*6dbdd20aSAndroid Build Coastguard Worker };
462*6dbdd20aSAndroid Build Coastguard Worker 
463*6dbdd20aSAndroid Build Coastguard Worker TestTracingPolicy* g_test_tracing_policy = new TestTracingPolicy();  // Leaked.
464*6dbdd20aSAndroid Build Coastguard Worker 
465*6dbdd20aSAndroid Build Coastguard Worker class ParsedIncrementalState {
466*6dbdd20aSAndroid Build Coastguard Worker  public:
ClearIfNeeded(const perfetto::protos::gen::TracePacket & packet)467*6dbdd20aSAndroid Build Coastguard Worker   void ClearIfNeeded(const perfetto::protos::gen::TracePacket& packet) {
468*6dbdd20aSAndroid Build Coastguard Worker     if (packet.sequence_flags() &
469*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
470*6dbdd20aSAndroid Build Coastguard Worker       incremental_state_was_cleared_ = true;
471*6dbdd20aSAndroid Build Coastguard Worker       categories_.clear();
472*6dbdd20aSAndroid Build Coastguard Worker       event_names_.clear();
473*6dbdd20aSAndroid Build Coastguard Worker       debug_annotation_names_.clear();
474*6dbdd20aSAndroid Build Coastguard Worker       seen_tracks_.clear();
475*6dbdd20aSAndroid Build Coastguard Worker     }
476*6dbdd20aSAndroid Build Coastguard Worker   }
477*6dbdd20aSAndroid Build Coastguard Worker 
Parse(const perfetto::protos::gen::TracePacket & packet)478*6dbdd20aSAndroid Build Coastguard Worker   void Parse(const perfetto::protos::gen::TracePacket& packet) {
479*6dbdd20aSAndroid Build Coastguard Worker     // Update incremental state.
480*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_interned_data()) {
481*6dbdd20aSAndroid Build Coastguard Worker       const auto& interned_data = packet.interned_data();
482*6dbdd20aSAndroid Build Coastguard Worker       for (const auto& it : interned_data.event_categories()) {
483*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(categories_.find(it.iid()), categories_.end());
484*6dbdd20aSAndroid Build Coastguard Worker         categories_[it.iid()] = it.name();
485*6dbdd20aSAndroid Build Coastguard Worker       }
486*6dbdd20aSAndroid Build Coastguard Worker       for (const auto& it : interned_data.event_names()) {
487*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(event_names_.find(it.iid()), event_names_.end());
488*6dbdd20aSAndroid Build Coastguard Worker         event_names_[it.iid()] = it.name();
489*6dbdd20aSAndroid Build Coastguard Worker       }
490*6dbdd20aSAndroid Build Coastguard Worker       for (const auto& it : interned_data.debug_annotation_names()) {
491*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(debug_annotation_names_.find(it.iid()),
492*6dbdd20aSAndroid Build Coastguard Worker                   debug_annotation_names_.end());
493*6dbdd20aSAndroid Build Coastguard Worker         debug_annotation_names_[it.iid()] = it.name();
494*6dbdd20aSAndroid Build Coastguard Worker       }
495*6dbdd20aSAndroid Build Coastguard Worker     }
496*6dbdd20aSAndroid Build Coastguard Worker   }
497*6dbdd20aSAndroid Build Coastguard Worker 
HasSeenTrack(uint64_t uuid) const498*6dbdd20aSAndroid Build Coastguard Worker   bool HasSeenTrack(uint64_t uuid) const {
499*6dbdd20aSAndroid Build Coastguard Worker     return seen_tracks_.count(uuid) != 0;
500*6dbdd20aSAndroid Build Coastguard Worker   }
501*6dbdd20aSAndroid Build Coastguard Worker 
InsertTrack(uint64_t uuid)502*6dbdd20aSAndroid Build Coastguard Worker   void InsertTrack(uint64_t uuid) { seen_tracks_.insert(uuid); }
503*6dbdd20aSAndroid Build Coastguard Worker 
GetCategory(uint64_t iid)504*6dbdd20aSAndroid Build Coastguard Worker   std::string GetCategory(uint64_t iid) { return categories_[iid]; }
505*6dbdd20aSAndroid Build Coastguard Worker 
GetEventName(const perfetto::protos::gen::TrackEvent & event)506*6dbdd20aSAndroid Build Coastguard Worker   std::string GetEventName(const perfetto::protos::gen::TrackEvent& event) {
507*6dbdd20aSAndroid Build Coastguard Worker     if (event.has_name_iid())
508*6dbdd20aSAndroid Build Coastguard Worker       return event_names_[event.name_iid()];
509*6dbdd20aSAndroid Build Coastguard Worker     return event.name();
510*6dbdd20aSAndroid Build Coastguard Worker   }
511*6dbdd20aSAndroid Build Coastguard Worker 
GetDebugAnnotationName(uint64_t iid)512*6dbdd20aSAndroid Build Coastguard Worker   std::string GetDebugAnnotationName(uint64_t iid) {
513*6dbdd20aSAndroid Build Coastguard Worker     return debug_annotation_names_[iid];
514*6dbdd20aSAndroid Build Coastguard Worker   }
515*6dbdd20aSAndroid Build Coastguard Worker 
WasCleared() const516*6dbdd20aSAndroid Build Coastguard Worker   bool WasCleared() const { return incremental_state_was_cleared_; }
517*6dbdd20aSAndroid Build Coastguard Worker 
518*6dbdd20aSAndroid Build Coastguard Worker  private:
519*6dbdd20aSAndroid Build Coastguard Worker   bool incremental_state_was_cleared_ = false;
520*6dbdd20aSAndroid Build Coastguard Worker   std::map<uint64_t, std::string> categories_;
521*6dbdd20aSAndroid Build Coastguard Worker   std::map<uint64_t, std::string> event_names_;
522*6dbdd20aSAndroid Build Coastguard Worker   std::map<uint64_t, std::string> debug_annotation_names_;
523*6dbdd20aSAndroid Build Coastguard Worker   std::set<uint64_t> seen_tracks_;
524*6dbdd20aSAndroid Build Coastguard Worker };
525*6dbdd20aSAndroid Build Coastguard Worker 
ReadSlicesFromTrace(const perfetto::protos::gen::Trace & parsed_trace,bool expect_incremental_state_cleared=true)526*6dbdd20aSAndroid Build Coastguard Worker std::vector<std::string> ReadSlicesFromTrace(
527*6dbdd20aSAndroid Build Coastguard Worker     const perfetto::protos::gen::Trace& parsed_trace,
528*6dbdd20aSAndroid Build Coastguard Worker     bool expect_incremental_state_cleared = true) {
529*6dbdd20aSAndroid Build Coastguard Worker   // Read back the trace, maintaining interning tables as we go.
530*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> slices;
531*6dbdd20aSAndroid Build Coastguard Worker   if (parsed_trace.packet().size() == 0)
532*6dbdd20aSAndroid Build Coastguard Worker     return slices;
533*6dbdd20aSAndroid Build Coastguard Worker   ParsedIncrementalState incremental_state;
534*6dbdd20aSAndroid Build Coastguard Worker 
535*6dbdd20aSAndroid Build Coastguard Worker   uint32_t sequence_id = 0;
536*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : parsed_trace.packet()) {
537*6dbdd20aSAndroid Build Coastguard Worker     incremental_state.ClearIfNeeded(packet);
538*6dbdd20aSAndroid Build Coastguard Worker 
539*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_descriptor()) {
540*6dbdd20aSAndroid Build Coastguard Worker       // Make sure we haven't seen any events on this track before the
541*6dbdd20aSAndroid Build Coastguard Worker       // descriptor was written.
542*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(
543*6dbdd20aSAndroid Build Coastguard Worker           incremental_state.HasSeenTrack(packet.track_descriptor().uuid()));
544*6dbdd20aSAndroid Build Coastguard Worker     }
545*6dbdd20aSAndroid Build Coastguard Worker 
546*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
547*6dbdd20aSAndroid Build Coastguard Worker       continue;
548*6dbdd20aSAndroid Build Coastguard Worker 
549*6dbdd20aSAndroid Build Coastguard Worker     // Make sure we only see track events on one sequence.
550*6dbdd20aSAndroid Build Coastguard Worker     if (packet.trusted_packet_sequence_id()) {
551*6dbdd20aSAndroid Build Coastguard Worker       if (!sequence_id)
552*6dbdd20aSAndroid Build Coastguard Worker         sequence_id = packet.trusted_packet_sequence_id();
553*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(sequence_id, packet.trusted_packet_sequence_id());
554*6dbdd20aSAndroid Build Coastguard Worker     }
555*6dbdd20aSAndroid Build Coastguard Worker 
556*6dbdd20aSAndroid Build Coastguard Worker     incremental_state.Parse(packet);
557*6dbdd20aSAndroid Build Coastguard Worker 
558*6dbdd20aSAndroid Build Coastguard Worker     const auto& track_event = packet.track_event();
559*6dbdd20aSAndroid Build Coastguard Worker     std::string slice;
560*6dbdd20aSAndroid Build Coastguard Worker 
561*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.has_track_uuid()) {
562*6dbdd20aSAndroid Build Coastguard Worker       incremental_state.InsertTrack(track_event.track_uuid());
563*6dbdd20aSAndroid Build Coastguard Worker       std::stringstream track;
564*6dbdd20aSAndroid Build Coastguard Worker       track << "[track=" << track_event.track_uuid() << "]";
565*6dbdd20aSAndroid Build Coastguard Worker       slice += track.str();
566*6dbdd20aSAndroid Build Coastguard Worker     }
567*6dbdd20aSAndroid Build Coastguard Worker 
568*6dbdd20aSAndroid Build Coastguard Worker     switch (track_event.type()) {
569*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN:
570*6dbdd20aSAndroid Build Coastguard Worker         slice += "B";
571*6dbdd20aSAndroid Build Coastguard Worker         break;
572*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_END:
573*6dbdd20aSAndroid Build Coastguard Worker         slice += "E";
574*6dbdd20aSAndroid Build Coastguard Worker         break;
575*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_INSTANT:
576*6dbdd20aSAndroid Build Coastguard Worker         slice += "I";
577*6dbdd20aSAndroid Build Coastguard Worker         break;
578*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_UNSPECIFIED: {
579*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(track_event.has_legacy_event());
580*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_FALSE(track_event.type());
581*6dbdd20aSAndroid Build Coastguard Worker         auto legacy_event = track_event.legacy_event();
582*6dbdd20aSAndroid Build Coastguard Worker         slice +=
583*6dbdd20aSAndroid Build Coastguard Worker             "Legacy_" + std::string(1, static_cast<char>(legacy_event.phase()));
584*6dbdd20aSAndroid Build Coastguard Worker         break;
585*6dbdd20aSAndroid Build Coastguard Worker       }
586*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_COUNTER:
587*6dbdd20aSAndroid Build Coastguard Worker         slice += "C";
588*6dbdd20aSAndroid Build Coastguard Worker         break;
589*6dbdd20aSAndroid Build Coastguard Worker       default:
590*6dbdd20aSAndroid Build Coastguard Worker         ADD_FAILURE();
591*6dbdd20aSAndroid Build Coastguard Worker     }
592*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.has_legacy_event()) {
593*6dbdd20aSAndroid Build Coastguard Worker       auto legacy_event = track_event.legacy_event();
594*6dbdd20aSAndroid Build Coastguard Worker       std::stringstream id;
595*6dbdd20aSAndroid Build Coastguard Worker       if (legacy_event.has_unscoped_id()) {
596*6dbdd20aSAndroid Build Coastguard Worker         id << "(unscoped_id=" << legacy_event.unscoped_id() << ")";
597*6dbdd20aSAndroid Build Coastguard Worker       } else if (legacy_event.has_local_id()) {
598*6dbdd20aSAndroid Build Coastguard Worker         id << "(local_id=" << legacy_event.local_id() << ")";
599*6dbdd20aSAndroid Build Coastguard Worker       } else if (legacy_event.has_global_id()) {
600*6dbdd20aSAndroid Build Coastguard Worker         id << "(global_id=" << legacy_event.global_id() << ")";
601*6dbdd20aSAndroid Build Coastguard Worker       } else if (legacy_event.has_bind_id()) {
602*6dbdd20aSAndroid Build Coastguard Worker         id << "(bind_id=" << legacy_event.bind_id() << ")";
603*6dbdd20aSAndroid Build Coastguard Worker       }
604*6dbdd20aSAndroid Build Coastguard Worker       if (legacy_event.has_id_scope())
605*6dbdd20aSAndroid Build Coastguard Worker         id << "(id_scope=\"" << legacy_event.id_scope() << "\")";
606*6dbdd20aSAndroid Build Coastguard Worker       if (legacy_event.use_async_tts())
607*6dbdd20aSAndroid Build Coastguard Worker         id << "(use_async_tts)";
608*6dbdd20aSAndroid Build Coastguard Worker       if (legacy_event.bind_to_enclosing())
609*6dbdd20aSAndroid Build Coastguard Worker         id << "(bind_to_enclosing)";
610*6dbdd20aSAndroid Build Coastguard Worker       if (legacy_event.has_flow_direction())
611*6dbdd20aSAndroid Build Coastguard Worker         id << "(flow_direction=" << legacy_event.flow_direction() << ")";
612*6dbdd20aSAndroid Build Coastguard Worker       if (legacy_event.has_pid_override())
613*6dbdd20aSAndroid Build Coastguard Worker         id << "(pid_override=" << legacy_event.pid_override() << ")";
614*6dbdd20aSAndroid Build Coastguard Worker       if (legacy_event.has_tid_override())
615*6dbdd20aSAndroid Build Coastguard Worker         id << "(tid_override=" << legacy_event.tid_override() << ")";
616*6dbdd20aSAndroid Build Coastguard Worker       slice += id.str();
617*6dbdd20aSAndroid Build Coastguard Worker     }
618*6dbdd20aSAndroid Build Coastguard Worker     size_t category_count = 0;
619*6dbdd20aSAndroid Build Coastguard Worker     for (const auto& it : track_event.category_iids())
620*6dbdd20aSAndroid Build Coastguard Worker       slice +=
621*6dbdd20aSAndroid Build Coastguard Worker           (category_count++ ? "," : ":") + incremental_state.GetCategory(it);
622*6dbdd20aSAndroid Build Coastguard Worker     for (const auto& it : track_event.categories())
623*6dbdd20aSAndroid Build Coastguard Worker       slice += (category_count++ ? ",$" : ":$") + it;
624*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.has_name() || track_event.has_name_iid())
625*6dbdd20aSAndroid Build Coastguard Worker       slice += "." + incremental_state.GetEventName(track_event);
626*6dbdd20aSAndroid Build Coastguard Worker 
627*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.debug_annotations_size()) {
628*6dbdd20aSAndroid Build Coastguard Worker       slice += "(";
629*6dbdd20aSAndroid Build Coastguard Worker       bool first_annotation = true;
630*6dbdd20aSAndroid Build Coastguard Worker       for (const auto& it : track_event.debug_annotations()) {
631*6dbdd20aSAndroid Build Coastguard Worker         if (!first_annotation) {
632*6dbdd20aSAndroid Build Coastguard Worker           slice += ",";
633*6dbdd20aSAndroid Build Coastguard Worker         }
634*6dbdd20aSAndroid Build Coastguard Worker         if (it.has_name_iid()) {
635*6dbdd20aSAndroid Build Coastguard Worker           slice += incremental_state.GetDebugAnnotationName(it.name_iid());
636*6dbdd20aSAndroid Build Coastguard Worker         } else {
637*6dbdd20aSAndroid Build Coastguard Worker           slice += it.name();
638*6dbdd20aSAndroid Build Coastguard Worker         }
639*6dbdd20aSAndroid Build Coastguard Worker         slice += "=";
640*6dbdd20aSAndroid Build Coastguard Worker         std::stringstream value;
641*6dbdd20aSAndroid Build Coastguard Worker         if (it.has_bool_value()) {
642*6dbdd20aSAndroid Build Coastguard Worker           value << "(bool)" << it.bool_value();
643*6dbdd20aSAndroid Build Coastguard Worker         } else if (it.has_uint_value()) {
644*6dbdd20aSAndroid Build Coastguard Worker           value << "(uint)" << it.uint_value();
645*6dbdd20aSAndroid Build Coastguard Worker         } else if (it.has_int_value()) {
646*6dbdd20aSAndroid Build Coastguard Worker           value << "(int)" << it.int_value();
647*6dbdd20aSAndroid Build Coastguard Worker         } else if (it.has_double_value()) {
648*6dbdd20aSAndroid Build Coastguard Worker           value << "(double)" << it.double_value();
649*6dbdd20aSAndroid Build Coastguard Worker         } else if (it.has_string_value()) {
650*6dbdd20aSAndroid Build Coastguard Worker           value << "(string)" << it.string_value();
651*6dbdd20aSAndroid Build Coastguard Worker         } else if (it.has_pointer_value()) {
652*6dbdd20aSAndroid Build Coastguard Worker           value << "(pointer)" << std::hex << it.pointer_value();
653*6dbdd20aSAndroid Build Coastguard Worker         } else if (it.has_legacy_json_value()) {
654*6dbdd20aSAndroid Build Coastguard Worker           value << "(json)" << it.legacy_json_value();
655*6dbdd20aSAndroid Build Coastguard Worker         } else if (it.has_nested_value()) {
656*6dbdd20aSAndroid Build Coastguard Worker           value << "(nested)" << it.nested_value().string_value();
657*6dbdd20aSAndroid Build Coastguard Worker         }
658*6dbdd20aSAndroid Build Coastguard Worker         slice += value.str();
659*6dbdd20aSAndroid Build Coastguard Worker         first_annotation = false;
660*6dbdd20aSAndroid Build Coastguard Worker       }
661*6dbdd20aSAndroid Build Coastguard Worker       slice += ")";
662*6dbdd20aSAndroid Build Coastguard Worker     }
663*6dbdd20aSAndroid Build Coastguard Worker 
664*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.flow_ids_old_size()) {
665*6dbdd20aSAndroid Build Coastguard Worker       slice += "(flow_ids_old=";
666*6dbdd20aSAndroid Build Coastguard Worker       std::stringstream value;
667*6dbdd20aSAndroid Build Coastguard Worker       bool first_annotation = true;
668*6dbdd20aSAndroid Build Coastguard Worker       for (uint64_t id : track_event.flow_ids_old()) {
669*6dbdd20aSAndroid Build Coastguard Worker         if (!first_annotation) {
670*6dbdd20aSAndroid Build Coastguard Worker           value << ",";
671*6dbdd20aSAndroid Build Coastguard Worker         }
672*6dbdd20aSAndroid Build Coastguard Worker         first_annotation = false;
673*6dbdd20aSAndroid Build Coastguard Worker         value << id;
674*6dbdd20aSAndroid Build Coastguard Worker       }
675*6dbdd20aSAndroid Build Coastguard Worker       slice += value.str() + ")";
676*6dbdd20aSAndroid Build Coastguard Worker     }
677*6dbdd20aSAndroid Build Coastguard Worker 
678*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.flow_ids_size()) {
679*6dbdd20aSAndroid Build Coastguard Worker       slice += "(flow_ids=";
680*6dbdd20aSAndroid Build Coastguard Worker       std::stringstream value;
681*6dbdd20aSAndroid Build Coastguard Worker       bool first_annotation = true;
682*6dbdd20aSAndroid Build Coastguard Worker       for (uint64_t id : track_event.flow_ids()) {
683*6dbdd20aSAndroid Build Coastguard Worker         if (!first_annotation) {
684*6dbdd20aSAndroid Build Coastguard Worker           value << ",";
685*6dbdd20aSAndroid Build Coastguard Worker         }
686*6dbdd20aSAndroid Build Coastguard Worker         first_annotation = false;
687*6dbdd20aSAndroid Build Coastguard Worker         value << id;
688*6dbdd20aSAndroid Build Coastguard Worker       }
689*6dbdd20aSAndroid Build Coastguard Worker       slice += value.str() + ")";
690*6dbdd20aSAndroid Build Coastguard Worker     }
691*6dbdd20aSAndroid Build Coastguard Worker 
692*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.terminating_flow_ids_old_size()) {
693*6dbdd20aSAndroid Build Coastguard Worker       slice += "(terminating_flow_ids_old=";
694*6dbdd20aSAndroid Build Coastguard Worker       std::stringstream value;
695*6dbdd20aSAndroid Build Coastguard Worker       bool first_annotation = true;
696*6dbdd20aSAndroid Build Coastguard Worker       for (uint64_t id : track_event.terminating_flow_ids_old()) {
697*6dbdd20aSAndroid Build Coastguard Worker         if (!first_annotation) {
698*6dbdd20aSAndroid Build Coastguard Worker           value << ",";
699*6dbdd20aSAndroid Build Coastguard Worker         }
700*6dbdd20aSAndroid Build Coastguard Worker         value << id;
701*6dbdd20aSAndroid Build Coastguard Worker         first_annotation = false;
702*6dbdd20aSAndroid Build Coastguard Worker       }
703*6dbdd20aSAndroid Build Coastguard Worker       slice += value.str() + ")";
704*6dbdd20aSAndroid Build Coastguard Worker     }
705*6dbdd20aSAndroid Build Coastguard Worker 
706*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.terminating_flow_ids_size()) {
707*6dbdd20aSAndroid Build Coastguard Worker       slice += "(terminating_flow_ids=";
708*6dbdd20aSAndroid Build Coastguard Worker       std::stringstream value;
709*6dbdd20aSAndroid Build Coastguard Worker       bool first_annotation = true;
710*6dbdd20aSAndroid Build Coastguard Worker       for (uint64_t id : track_event.terminating_flow_ids()) {
711*6dbdd20aSAndroid Build Coastguard Worker         if (!first_annotation) {
712*6dbdd20aSAndroid Build Coastguard Worker           value << ",";
713*6dbdd20aSAndroid Build Coastguard Worker         }
714*6dbdd20aSAndroid Build Coastguard Worker         value << id;
715*6dbdd20aSAndroid Build Coastguard Worker         first_annotation = false;
716*6dbdd20aSAndroid Build Coastguard Worker       }
717*6dbdd20aSAndroid Build Coastguard Worker       slice += value.str() + ")";
718*6dbdd20aSAndroid Build Coastguard Worker     }
719*6dbdd20aSAndroid Build Coastguard Worker 
720*6dbdd20aSAndroid Build Coastguard Worker     slices.push_back(slice);
721*6dbdd20aSAndroid Build Coastguard Worker   }
722*6dbdd20aSAndroid Build Coastguard Worker   if (expect_incremental_state_cleared) {
723*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(incremental_state.WasCleared());
724*6dbdd20aSAndroid Build Coastguard Worker   }
725*6dbdd20aSAndroid Build Coastguard Worker   return slices;
726*6dbdd20aSAndroid Build Coastguard Worker }
727*6dbdd20aSAndroid Build Coastguard Worker 
ReadSlicesFromTrace(const std::vector<char> & raw_trace,bool expect_incremental_state_cleared=true)728*6dbdd20aSAndroid Build Coastguard Worker std::vector<std::string> ReadSlicesFromTrace(
729*6dbdd20aSAndroid Build Coastguard Worker     const std::vector<char>& raw_trace,
730*6dbdd20aSAndroid Build Coastguard Worker     bool expect_incremental_state_cleared = true) {
731*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_GE(raw_trace.size(), 0u);
732*6dbdd20aSAndroid Build Coastguard Worker 
733*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace parsed_trace;
734*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
735*6dbdd20aSAndroid Build Coastguard Worker   return ReadSlicesFromTrace(parsed_trace, expect_incremental_state_cleared);
736*6dbdd20aSAndroid Build Coastguard Worker }
737*6dbdd20aSAndroid Build Coastguard Worker 
WaitForOneProducerConnected(perfetto::TracingSession * session)738*6dbdd20aSAndroid Build Coastguard Worker bool WaitForOneProducerConnected(perfetto::TracingSession* session) {
739*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < 100; i++) {
740*6dbdd20aSAndroid Build Coastguard Worker     // Blocking read.
741*6dbdd20aSAndroid Build Coastguard Worker     auto result = session->QueryServiceStateBlocking();
742*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TracingServiceState state;
743*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(result.success);
744*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(state.ParseFromArray(result.service_state_data.data(),
745*6dbdd20aSAndroid Build Coastguard Worker                                      result.service_state_data.size()));
746*6dbdd20aSAndroid Build Coastguard Worker     // The producer has connected to the new restarted system service.
747*6dbdd20aSAndroid Build Coastguard Worker     if (state.producers().size() == 1) {
748*6dbdd20aSAndroid Build Coastguard Worker       return true;
749*6dbdd20aSAndroid Build Coastguard Worker     }
750*6dbdd20aSAndroid Build Coastguard Worker     std::this_thread::sleep_for(std::chrono::milliseconds(100));
751*6dbdd20aSAndroid Build Coastguard Worker   }
752*6dbdd20aSAndroid Build Coastguard Worker   ADD_FAILURE() << "Producer not connected";
753*6dbdd20aSAndroid Build Coastguard Worker   return false;
754*6dbdd20aSAndroid Build Coastguard Worker }
755*6dbdd20aSAndroid Build Coastguard Worker 
756*6dbdd20aSAndroid Build Coastguard Worker // -------------------------
757*6dbdd20aSAndroid Build Coastguard Worker // Declaration of test class
758*6dbdd20aSAndroid Build Coastguard Worker // -------------------------
759*6dbdd20aSAndroid Build Coastguard Worker class PerfettoApiTest : public ::testing::TestWithParam<perfetto::BackendType> {
760*6dbdd20aSAndroid Build Coastguard Worker  public:
761*6dbdd20aSAndroid Build Coastguard Worker   static PerfettoApiTest* instance;
762*6dbdd20aSAndroid Build Coastguard Worker 
SetUp()763*6dbdd20aSAndroid Build Coastguard Worker   void SetUp() override {
764*6dbdd20aSAndroid Build Coastguard Worker     instance = this;
765*6dbdd20aSAndroid Build Coastguard Worker     g_test_tracing_policy->should_allow_consumer_connection = true;
766*6dbdd20aSAndroid Build Coastguard Worker 
767*6dbdd20aSAndroid Build Coastguard Worker     // Start a fresh system service for this test, tearing down any previous
768*6dbdd20aSAndroid Build Coastguard Worker     // service that was running.
769*6dbdd20aSAndroid Build Coastguard Worker     if (GetParam() == perfetto::kSystemBackend) {
770*6dbdd20aSAndroid Build Coastguard Worker       system_service_ = perfetto::test::SystemService::Start();
771*6dbdd20aSAndroid Build Coastguard Worker       // If the system backend isn't supported, skip all system backend tests.
772*6dbdd20aSAndroid Build Coastguard Worker       if (!system_service_.valid()) {
773*6dbdd20aSAndroid Build Coastguard Worker         GTEST_SKIP();
774*6dbdd20aSAndroid Build Coastguard Worker       }
775*6dbdd20aSAndroid Build Coastguard Worker     }
776*6dbdd20aSAndroid Build Coastguard Worker 
777*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(perfetto::Tracing::IsInitialized());
778*6dbdd20aSAndroid Build Coastguard Worker     TracingInitArgs args;
779*6dbdd20aSAndroid Build Coastguard Worker     args.backends = GetParam();
780*6dbdd20aSAndroid Build Coastguard Worker     args.tracing_policy = g_test_tracing_policy;
781*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Tracing::Initialize(args);
782*6dbdd20aSAndroid Build Coastguard Worker     RegisterDataSource<MockDataSource>("my_data_source");
783*6dbdd20aSAndroid Build Coastguard Worker     {
784*6dbdd20aSAndroid Build Coastguard Worker       perfetto::DataSourceDescriptor dsd;
785*6dbdd20aSAndroid Build Coastguard Worker       dsd.set_name("CustomDataSource");
786*6dbdd20aSAndroid Build Coastguard Worker       CustomDataSource::Register(dsd);
787*6dbdd20aSAndroid Build Coastguard Worker     }
788*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::Register();
789*6dbdd20aSAndroid Build Coastguard Worker 
790*6dbdd20aSAndroid Build Coastguard Worker     // Make sure our data source always has a valid handle.
791*6dbdd20aSAndroid Build Coastguard Worker     data_sources_["my_data_source"];
792*6dbdd20aSAndroid Build Coastguard Worker 
793*6dbdd20aSAndroid Build Coastguard Worker     // If this wasn't the first test to run in this process, any producers
794*6dbdd20aSAndroid Build Coastguard Worker     // connected to the old system service will have been disconnected by the
795*6dbdd20aSAndroid Build Coastguard Worker     // service restarting above. Wait for all producers to connect again before
796*6dbdd20aSAndroid Build Coastguard Worker     // proceeding with the test.
797*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::SyncProducers();
798*6dbdd20aSAndroid Build Coastguard Worker 
799*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::DisableReconnectLimit();
800*6dbdd20aSAndroid Build Coastguard Worker   }
801*6dbdd20aSAndroid Build Coastguard Worker 
TearDown()802*6dbdd20aSAndroid Build Coastguard Worker   void TearDown() override {
803*6dbdd20aSAndroid Build Coastguard Worker     instance = nullptr;
804*6dbdd20aSAndroid Build Coastguard Worker     sessions_.clear();
805*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::TracingMuxerImplInternalsForTest::
806*6dbdd20aSAndroid Build Coastguard Worker         ClearDataSourceTlsStateOnReset<MockDataSource>();
807*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::TracingMuxerImplInternalsForTest::
808*6dbdd20aSAndroid Build Coastguard Worker         ClearDataSourceTlsStateOnReset<CustomDataSource>();
809*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::TracingMuxerImplInternalsForTest::
810*6dbdd20aSAndroid Build Coastguard Worker         ClearDataSourceTlsStateOnReset<perfetto::TrackEvent>();
811*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Tracing::ResetForTesting();
812*6dbdd20aSAndroid Build Coastguard Worker   }
813*6dbdd20aSAndroid Build Coastguard Worker 
814*6dbdd20aSAndroid Build Coastguard Worker   template <typename DerivedDataSource>
RegisterDataSource(std::string name)815*6dbdd20aSAndroid Build Coastguard Worker   TestDataSourceHandle* RegisterDataSource(std::string name) {
816*6dbdd20aSAndroid Build Coastguard Worker     perfetto::DataSourceDescriptor dsd;
817*6dbdd20aSAndroid Build Coastguard Worker     dsd.set_name(name);
818*6dbdd20aSAndroid Build Coastguard Worker     return RegisterDataSource<DerivedDataSource>(dsd);
819*6dbdd20aSAndroid Build Coastguard Worker   }
820*6dbdd20aSAndroid Build Coastguard Worker 
821*6dbdd20aSAndroid Build Coastguard Worker   template <typename DerivedDataSource>
RegisterDataSource(const perfetto::DataSourceDescriptor & dsd)822*6dbdd20aSAndroid Build Coastguard Worker   TestDataSourceHandle* RegisterDataSource(
823*6dbdd20aSAndroid Build Coastguard Worker       const perfetto::DataSourceDescriptor& dsd) {
824*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(data_sources_.count(dsd.name()), 0u);
825*6dbdd20aSAndroid Build Coastguard Worker     TestDataSourceHandle* handle = &data_sources_[dsd.name()];
826*6dbdd20aSAndroid Build Coastguard Worker     DerivedDataSource::Register(dsd);
827*6dbdd20aSAndroid Build Coastguard Worker     return handle;
828*6dbdd20aSAndroid Build Coastguard Worker   }
829*6dbdd20aSAndroid Build Coastguard Worker 
830*6dbdd20aSAndroid Build Coastguard Worker   template <typename DerivedDataSource>
UpdateDataSource(const perfetto::DataSourceDescriptor & dsd)831*6dbdd20aSAndroid Build Coastguard Worker   TestDataSourceHandle* UpdateDataSource(
832*6dbdd20aSAndroid Build Coastguard Worker       const perfetto::DataSourceDescriptor& dsd) {
833*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(data_sources_.count(dsd.name()), 1u);
834*6dbdd20aSAndroid Build Coastguard Worker     TestDataSourceHandle* handle = &data_sources_[dsd.name()];
835*6dbdd20aSAndroid Build Coastguard Worker     DerivedDataSource::UpdateDescriptor(dsd);
836*6dbdd20aSAndroid Build Coastguard Worker     return handle;
837*6dbdd20aSAndroid Build Coastguard Worker   }
838*6dbdd20aSAndroid Build Coastguard Worker 
NewTrace(const perfetto::TraceConfig & cfg,int fd=-1)839*6dbdd20aSAndroid Build Coastguard Worker   TestTracingSessionHandle* NewTrace(const perfetto::TraceConfig& cfg,
840*6dbdd20aSAndroid Build Coastguard Worker                                      int fd = -1) {
841*6dbdd20aSAndroid Build Coastguard Worker     return NewTrace(cfg, /*backend_type=*/GetParam(), fd);
842*6dbdd20aSAndroid Build Coastguard Worker   }
843*6dbdd20aSAndroid Build Coastguard Worker 
NewTrace(const perfetto::TraceConfig & cfg,perfetto::BackendType backend_type,int fd=-1)844*6dbdd20aSAndroid Build Coastguard Worker   TestTracingSessionHandle* NewTrace(const perfetto::TraceConfig& cfg,
845*6dbdd20aSAndroid Build Coastguard Worker                                      perfetto::BackendType backend_type,
846*6dbdd20aSAndroid Build Coastguard Worker                                      int fd = -1) {
847*6dbdd20aSAndroid Build Coastguard Worker     sessions_.emplace_back();
848*6dbdd20aSAndroid Build Coastguard Worker     TestTracingSessionHandle* handle = &sessions_.back();
849*6dbdd20aSAndroid Build Coastguard Worker     handle->session = perfetto::Tracing::NewTrace(backend_type);
850*6dbdd20aSAndroid Build Coastguard Worker     handle->session->SetOnStopCallback([handle] { handle->on_stop.Notify(); });
851*6dbdd20aSAndroid Build Coastguard Worker     handle->session->Setup(cfg, fd);
852*6dbdd20aSAndroid Build Coastguard Worker     return handle;
853*6dbdd20aSAndroid Build Coastguard Worker   }
854*6dbdd20aSAndroid Build Coastguard Worker 
NewTraceWithCategories(std::vector<std::string> categories,perfetto::protos::gen::TrackEventConfig te_cfg={},perfetto::TraceConfig cfg={})855*6dbdd20aSAndroid Build Coastguard Worker   TestTracingSessionHandle* NewTraceWithCategories(
856*6dbdd20aSAndroid Build Coastguard Worker       std::vector<std::string> categories,
857*6dbdd20aSAndroid Build Coastguard Worker       perfetto::protos::gen::TrackEventConfig te_cfg = {},
858*6dbdd20aSAndroid Build Coastguard Worker       perfetto::TraceConfig cfg = {}) {
859*6dbdd20aSAndroid Build Coastguard Worker     cfg.set_duration_ms(500);
860*6dbdd20aSAndroid Build Coastguard Worker     cfg.add_buffers()->set_size_kb(1024);
861*6dbdd20aSAndroid Build Coastguard Worker     auto* ds_cfg = cfg.add_data_sources()->mutable_config();
862*6dbdd20aSAndroid Build Coastguard Worker     ds_cfg->set_name("track_event");
863*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_disabled_categories("*");
864*6dbdd20aSAndroid Build Coastguard Worker     for (const auto& category : categories)
865*6dbdd20aSAndroid Build Coastguard Worker       te_cfg.add_enabled_categories(category);
866*6dbdd20aSAndroid Build Coastguard Worker     ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
867*6dbdd20aSAndroid Build Coastguard Worker 
868*6dbdd20aSAndroid Build Coastguard Worker     return NewTrace(cfg);
869*6dbdd20aSAndroid Build Coastguard Worker   }
870*6dbdd20aSAndroid Build Coastguard Worker 
ReadLogMessagesFromTrace(perfetto::TracingSession * tracing_session)871*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> ReadLogMessagesFromTrace(
872*6dbdd20aSAndroid Build Coastguard Worker       perfetto::TracingSession* tracing_session) {
873*6dbdd20aSAndroid Build Coastguard Worker     std::vector<char> raw_trace = tracing_session->ReadTraceBlocking();
874*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_GE(raw_trace.size(), 0u);
875*6dbdd20aSAndroid Build Coastguard Worker 
876*6dbdd20aSAndroid Build Coastguard Worker     // Read back the trace, maintaining interning tables as we go.
877*6dbdd20aSAndroid Build Coastguard Worker     std::vector<std::string> log_messages;
878*6dbdd20aSAndroid Build Coastguard Worker     std::map<uint64_t, std::string> log_message_bodies;
879*6dbdd20aSAndroid Build Coastguard Worker     std::map<uint64_t, perfetto::protos::gen::SourceLocation> source_locations;
880*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::Trace parsed_trace;
881*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(
882*6dbdd20aSAndroid Build Coastguard Worker         parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
883*6dbdd20aSAndroid Build Coastguard Worker 
884*6dbdd20aSAndroid Build Coastguard Worker     for (const auto& packet : parsed_trace.packet()) {
885*6dbdd20aSAndroid Build Coastguard Worker       if (!packet.has_track_event())
886*6dbdd20aSAndroid Build Coastguard Worker         continue;
887*6dbdd20aSAndroid Build Coastguard Worker 
888*6dbdd20aSAndroid Build Coastguard Worker       if (packet.has_interned_data()) {
889*6dbdd20aSAndroid Build Coastguard Worker         const auto& interned_data = packet.interned_data();
890*6dbdd20aSAndroid Build Coastguard Worker         for (const auto& it : interned_data.log_message_body()) {
891*6dbdd20aSAndroid Build Coastguard Worker           EXPECT_GE(it.iid(), 1u);
892*6dbdd20aSAndroid Build Coastguard Worker           EXPECT_EQ(log_message_bodies.find(it.iid()),
893*6dbdd20aSAndroid Build Coastguard Worker                     log_message_bodies.end());
894*6dbdd20aSAndroid Build Coastguard Worker           log_message_bodies[it.iid()] = it.body();
895*6dbdd20aSAndroid Build Coastguard Worker         }
896*6dbdd20aSAndroid Build Coastguard Worker         for (const auto& it : interned_data.source_locations()) {
897*6dbdd20aSAndroid Build Coastguard Worker           EXPECT_GE(it.iid(), 1u);
898*6dbdd20aSAndroid Build Coastguard Worker           EXPECT_EQ(source_locations.find(it.iid()), source_locations.end());
899*6dbdd20aSAndroid Build Coastguard Worker           source_locations[it.iid()] = it;
900*6dbdd20aSAndroid Build Coastguard Worker         }
901*6dbdd20aSAndroid Build Coastguard Worker       }
902*6dbdd20aSAndroid Build Coastguard Worker       const auto& track_event = packet.track_event();
903*6dbdd20aSAndroid Build Coastguard Worker       if (track_event.type() !=
904*6dbdd20aSAndroid Build Coastguard Worker           perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN)
905*6dbdd20aSAndroid Build Coastguard Worker         continue;
906*6dbdd20aSAndroid Build Coastguard Worker 
907*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(track_event.has_log_message());
908*6dbdd20aSAndroid Build Coastguard Worker       const auto& log = track_event.log_message();
909*6dbdd20aSAndroid Build Coastguard Worker       if (log.source_location_iid()) {
910*6dbdd20aSAndroid Build Coastguard Worker         std::stringstream msg;
911*6dbdd20aSAndroid Build Coastguard Worker         const auto& source_location =
912*6dbdd20aSAndroid Build Coastguard Worker             source_locations[log.source_location_iid()];
913*6dbdd20aSAndroid Build Coastguard Worker         msg << source_location.function_name() << "("
914*6dbdd20aSAndroid Build Coastguard Worker             << source_location.file_name() << ":"
915*6dbdd20aSAndroid Build Coastguard Worker             << source_location.line_number()
916*6dbdd20aSAndroid Build Coastguard Worker             << "): " << log_message_bodies[log.body_iid()];
917*6dbdd20aSAndroid Build Coastguard Worker         log_messages.emplace_back(msg.str());
918*6dbdd20aSAndroid Build Coastguard Worker       } else {
919*6dbdd20aSAndroid Build Coastguard Worker         log_messages.emplace_back(log_message_bodies[log.body_iid()]);
920*6dbdd20aSAndroid Build Coastguard Worker       }
921*6dbdd20aSAndroid Build Coastguard Worker     }
922*6dbdd20aSAndroid Build Coastguard Worker     return log_messages;
923*6dbdd20aSAndroid Build Coastguard Worker   }
924*6dbdd20aSAndroid Build Coastguard Worker 
ReadSlicesFromTraceSession(perfetto::TracingSession * tracing_session)925*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> ReadSlicesFromTraceSession(
926*6dbdd20aSAndroid Build Coastguard Worker       perfetto::TracingSession* tracing_session) {
927*6dbdd20aSAndroid Build Coastguard Worker     return ReadSlicesFromTrace(tracing_session->ReadTraceBlocking());
928*6dbdd20aSAndroid Build Coastguard Worker   }
929*6dbdd20aSAndroid Build Coastguard Worker 
StopSessionAndReadSlicesFromTrace(TestTracingSessionHandle * tracing_session)930*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> StopSessionAndReadSlicesFromTrace(
931*6dbdd20aSAndroid Build Coastguard Worker       TestTracingSessionHandle* tracing_session) {
932*6dbdd20aSAndroid Build Coastguard Worker     return ReadSlicesFromTrace(StopSessionAndReturnBytes(tracing_session));
933*6dbdd20aSAndroid Build Coastguard Worker   }
934*6dbdd20aSAndroid Build Coastguard Worker 
GetMainThreadPacketSequenceId(const perfetto::protos::gen::Trace & trace)935*6dbdd20aSAndroid Build Coastguard Worker   uint32_t GetMainThreadPacketSequenceId(
936*6dbdd20aSAndroid Build Coastguard Worker       const perfetto::protos::gen::Trace& trace) {
937*6dbdd20aSAndroid Build Coastguard Worker     for (const auto& packet : trace.packet()) {
938*6dbdd20aSAndroid Build Coastguard Worker       if (packet.has_track_descriptor() &&
939*6dbdd20aSAndroid Build Coastguard Worker           packet.track_descriptor().thread().tid() ==
940*6dbdd20aSAndroid Build Coastguard Worker               static_cast<int32_t>(perfetto::base::GetThreadId())) {
941*6dbdd20aSAndroid Build Coastguard Worker         return packet.trusted_packet_sequence_id();
942*6dbdd20aSAndroid Build Coastguard Worker       }
943*6dbdd20aSAndroid Build Coastguard Worker     }
944*6dbdd20aSAndroid Build Coastguard Worker     ADD_FAILURE() << "Main thread not found";
945*6dbdd20aSAndroid Build Coastguard Worker     return 0;
946*6dbdd20aSAndroid Build Coastguard Worker   }
947*6dbdd20aSAndroid Build Coastguard Worker 
StopSessionAndReturnBytes(TestTracingSessionHandle * tracing_session)948*6dbdd20aSAndroid Build Coastguard Worker   static std::vector<char> StopSessionAndReturnBytes(
949*6dbdd20aSAndroid Build Coastguard Worker       TestTracingSessionHandle* tracing_session) {
950*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::Flush();
951*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StopBlocking();
952*6dbdd20aSAndroid Build Coastguard Worker     return tracing_session->get()->ReadTraceBlocking();
953*6dbdd20aSAndroid Build Coastguard Worker   }
954*6dbdd20aSAndroid Build Coastguard Worker 
StopSessionAndReturnParsedTrace(TestTracingSessionHandle * tracing_session)955*6dbdd20aSAndroid Build Coastguard Worker   static perfetto::protos::gen::Trace StopSessionAndReturnParsedTrace(
956*6dbdd20aSAndroid Build Coastguard Worker       TestTracingSessionHandle* tracing_session) {
957*6dbdd20aSAndroid Build Coastguard Worker     std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
958*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::Trace trace;
959*6dbdd20aSAndroid Build Coastguard Worker     if (trace.ParseFromArray(raw_trace.data(), raw_trace.size())) {
960*6dbdd20aSAndroid Build Coastguard Worker       return trace;
961*6dbdd20aSAndroid Build Coastguard Worker     } else {
962*6dbdd20aSAndroid Build Coastguard Worker       ADD_FAILURE() << "trace.ParseFromArray failed";
963*6dbdd20aSAndroid Build Coastguard Worker       return perfetto::protos::gen::Trace();
964*6dbdd20aSAndroid Build Coastguard Worker     }
965*6dbdd20aSAndroid Build Coastguard Worker   }
966*6dbdd20aSAndroid Build Coastguard Worker 
967*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SystemService system_service_;
968*6dbdd20aSAndroid Build Coastguard Worker   std::map<std::string, TestDataSourceHandle> data_sources_;
969*6dbdd20aSAndroid Build Coastguard Worker   std::list<TestTracingSessionHandle> sessions_;  // Needs stable pointers.
970*6dbdd20aSAndroid Build Coastguard Worker };
971*6dbdd20aSAndroid Build Coastguard Worker 
972*6dbdd20aSAndroid Build Coastguard Worker // ---------------------------------------------
973*6dbdd20aSAndroid Build Coastguard Worker // Definitions for non-inlineable helper methods
974*6dbdd20aSAndroid Build Coastguard Worker // ---------------------------------------------
975*6dbdd20aSAndroid Build Coastguard Worker PerfettoApiTest* PerfettoApiTest::instance;
976*6dbdd20aSAndroid Build Coastguard Worker 
OnSetup(const SetupArgs & args)977*6dbdd20aSAndroid Build Coastguard Worker void MockDataSource::OnSetup(const SetupArgs& args) {
978*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(handle_, nullptr);
979*6dbdd20aSAndroid Build Coastguard Worker   auto it = PerfettoApiTest::instance->data_sources_.find(args.config->name());
980*6dbdd20aSAndroid Build Coastguard Worker 
981*6dbdd20aSAndroid Build Coastguard Worker   // We should not see an OnSetup for a data source that we didn't register
982*6dbdd20aSAndroid Build Coastguard Worker   // before via PerfettoApiTest::RegisterDataSource().
983*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(it, PerfettoApiTest::instance->data_sources_.end());
984*6dbdd20aSAndroid Build Coastguard Worker   handle_ = &it->second;
985*6dbdd20aSAndroid Build Coastguard Worker   handle_->config = *args.config;  // Deliberate copy.
986*6dbdd20aSAndroid Build Coastguard Worker   handle_->on_setup.Notify();
987*6dbdd20aSAndroid Build Coastguard Worker }
988*6dbdd20aSAndroid Build Coastguard Worker 
OnStart(const StartArgs &)989*6dbdd20aSAndroid Build Coastguard Worker void MockDataSource::OnStart(const StartArgs&) {
990*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(handle_, nullptr);
991*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(handle_->is_datasource_started);
992*6dbdd20aSAndroid Build Coastguard Worker   handle_->is_datasource_started = true;
993*6dbdd20aSAndroid Build Coastguard Worker   if (handle_->on_start_callback)
994*6dbdd20aSAndroid Build Coastguard Worker     handle_->on_start_callback();
995*6dbdd20aSAndroid Build Coastguard Worker   handle_->on_start.Notify();
996*6dbdd20aSAndroid Build Coastguard Worker }
997*6dbdd20aSAndroid Build Coastguard Worker 
OnStop(const StopArgs & args)998*6dbdd20aSAndroid Build Coastguard Worker void MockDataSource::OnStop(const StopArgs& args) {
999*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(handle_, nullptr);
1000*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(handle_->is_datasource_started);
1001*6dbdd20aSAndroid Build Coastguard Worker   handle_->is_datasource_started = false;
1002*6dbdd20aSAndroid Build Coastguard Worker   if (handle_->handle_stop_asynchronously)
1003*6dbdd20aSAndroid Build Coastguard Worker     handle_->async_stop_closure = args.HandleStopAsynchronously();
1004*6dbdd20aSAndroid Build Coastguard Worker   if (handle_->on_stop_callback)
1005*6dbdd20aSAndroid Build Coastguard Worker     handle_->on_stop_callback();
1006*6dbdd20aSAndroid Build Coastguard Worker   handle_->on_stop.Notify();
1007*6dbdd20aSAndroid Build Coastguard Worker }
1008*6dbdd20aSAndroid Build Coastguard Worker 
OnFlush(const FlushArgs & args)1009*6dbdd20aSAndroid Build Coastguard Worker void MockDataSource::OnFlush(const FlushArgs& args) {
1010*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(handle_, nullptr);
1011*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(handle_->is_datasource_started);
1012*6dbdd20aSAndroid Build Coastguard Worker   if (handle_->handle_flush_asynchronously)
1013*6dbdd20aSAndroid Build Coastguard Worker     handle_->async_flush_closure = args.HandleFlushAsynchronously();
1014*6dbdd20aSAndroid Build Coastguard Worker   if (handle_->on_flush_callback) {
1015*6dbdd20aSAndroid Build Coastguard Worker     handle_->on_flush_callback(args.flush_flags);
1016*6dbdd20aSAndroid Build Coastguard Worker   }
1017*6dbdd20aSAndroid Build Coastguard Worker   handle_->on_flush.Notify();
1018*6dbdd20aSAndroid Build Coastguard Worker }
1019*6dbdd20aSAndroid Build Coastguard Worker 
1020*6dbdd20aSAndroid Build Coastguard Worker // -------------
1021*6dbdd20aSAndroid Build Coastguard Worker // Test fixtures
1022*6dbdd20aSAndroid Build Coastguard Worker // -------------
1023*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,StartAndStopWithoutDataSources)1024*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, StartAndStopWithoutDataSources) {
1025*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session without any data sources configured.
1026*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
1027*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
1028*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
1029*6dbdd20aSAndroid Build Coastguard Worker   // This should not timeout.
1030*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1031*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
1032*6dbdd20aSAndroid Build Coastguard Worker }
1033*6dbdd20aSAndroid Build Coastguard Worker 
1034*6dbdd20aSAndroid Build Coastguard Worker // Disabled by default because it leaks tracing sessions into subsequent tests,
1035*6dbdd20aSAndroid Build Coastguard Worker // which can result in the per-uid tracing session limit (5) to be hit in later
1036*6dbdd20aSAndroid Build Coastguard Worker // tests.
1037*6dbdd20aSAndroid Build Coastguard Worker // TODO(b/261493947): fix or remove.
TEST_P(PerfettoApiTest,DISABLED_TrackEventStartStopAndDestroy)1038*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, DISABLED_TrackEventStartStopAndDestroy) {
1039*6dbdd20aSAndroid Build Coastguard Worker   // This test used to cause a use after free as the tracing session got
1040*6dbdd20aSAndroid Build Coastguard Worker   // destroyed. It needed to be run approximately 2000 times to catch it so test
1041*6dbdd20aSAndroid Build Coastguard Worker   // with --gtest_repeat=3000 (less if running under GDB).
1042*6dbdd20aSAndroid Build Coastguard Worker 
1043*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
1044*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
1045*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
1046*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
1047*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1048*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
1049*6dbdd20aSAndroid Build Coastguard Worker 
1050*6dbdd20aSAndroid Build Coastguard Worker   // Create five new trace sessions.
1051*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::unique_ptr<perfetto::TracingSession>> sessions;
1052*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < 5; ++i) {
1053*6dbdd20aSAndroid Build Coastguard Worker     sessions.push_back(perfetto::Tracing::NewTrace(/*BackendType=*/GetParam()));
1054*6dbdd20aSAndroid Build Coastguard Worker     sessions[i]->Setup(cfg);
1055*6dbdd20aSAndroid Build Coastguard Worker     sessions[i]->Start();
1056*6dbdd20aSAndroid Build Coastguard Worker     sessions[i]->Stop();
1057*6dbdd20aSAndroid Build Coastguard Worker   }
1058*6dbdd20aSAndroid Build Coastguard Worker }
1059*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventStartStopAndStopBlocking)1060*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventStartStopAndStopBlocking) {
1061*6dbdd20aSAndroid Build Coastguard Worker   // This test used to cause a deadlock (due to StopBlocking() after the session
1062*6dbdd20aSAndroid Build Coastguard Worker   // already stopped). This usually occurred within 1 or 2 runs of the test so
1063*6dbdd20aSAndroid Build Coastguard Worker   // use --gtest_repeat=10
1064*6dbdd20aSAndroid Build Coastguard Worker 
1065*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
1066*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
1067*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
1068*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
1069*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1070*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
1071*6dbdd20aSAndroid Build Coastguard Worker 
1072*6dbdd20aSAndroid Build Coastguard Worker   // Create five new trace sessions.
1073*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::unique_ptr<perfetto::TracingSession>> sessions;
1074*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < 5; ++i) {
1075*6dbdd20aSAndroid Build Coastguard Worker     sessions.push_back(perfetto::Tracing::NewTrace(/*BackendType=*/GetParam()));
1076*6dbdd20aSAndroid Build Coastguard Worker     sessions[i]->Setup(cfg);
1077*6dbdd20aSAndroid Build Coastguard Worker     sessions[i]->Start();
1078*6dbdd20aSAndroid Build Coastguard Worker     sessions[i]->Stop();
1079*6dbdd20aSAndroid Build Coastguard Worker   }
1080*6dbdd20aSAndroid Build Coastguard Worker   for (auto& session : sessions) {
1081*6dbdd20aSAndroid Build Coastguard Worker     session->StopBlocking();
1082*6dbdd20aSAndroid Build Coastguard Worker   }
1083*6dbdd20aSAndroid Build Coastguard Worker }
1084*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ChangeTraceConfiguration)1085*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ChangeTraceConfiguration) {
1086*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
1087*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig trace_config;
1088*6dbdd20aSAndroid Build Coastguard Worker   trace_config.set_duration_ms(2000);
1089*6dbdd20aSAndroid Build Coastguard Worker   trace_config.add_buffers()->set_size_kb(1024);
1090*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = trace_config.add_data_sources();
1091*6dbdd20aSAndroid Build Coastguard Worker 
1092*6dbdd20aSAndroid Build Coastguard Worker   // Configure track events with category "foo".
1093*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = data_source->mutable_config();
1094*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
1095*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TrackEventConfig te_cfg;
1096*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.add_disabled_categories("*");
1097*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.add_enabled_categories("foo");
1098*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
1099*6dbdd20aSAndroid Build Coastguard Worker 
1100*6dbdd20aSAndroid Build Coastguard Worker   // Initially, exclude all producers (the client library's producer is named
1101*6dbdd20aSAndroid Build Coastguard Worker   // after current process's name, which will not match
1102*6dbdd20aSAndroid Build Coastguard Worker   // "all_producers_excluded").
1103*6dbdd20aSAndroid Build Coastguard Worker   data_source->add_producer_name_filter("all_producers_excluded");
1104*6dbdd20aSAndroid Build Coastguard Worker 
1105*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(trace_config);
1106*6dbdd20aSAndroid Build Coastguard Worker 
1107*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1108*6dbdd20aSAndroid Build Coastguard Worker 
1109*6dbdd20aSAndroid Build Coastguard Worker   // Emit a first trace event, this one should be filtered out due
1110*6dbdd20aSAndroid Build Coastguard Worker   // to the mismatching producer name filter.
1111*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "EventFilteredOut");
1112*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
1113*6dbdd20aSAndroid Build Coastguard Worker 
1114*6dbdd20aSAndroid Build Coastguard Worker   // Remove the producer name filter by changing configs.
1115*6dbdd20aSAndroid Build Coastguard Worker   data_source->clear_producer_name_filter();
1116*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->ChangeTraceConfig(trace_config);
1117*6dbdd20aSAndroid Build Coastguard Worker 
1118*6dbdd20aSAndroid Build Coastguard Worker   // We don't have a blocking version of ChangeTraceConfig, because there is
1119*6dbdd20aSAndroid Build Coastguard Worker   // currently no response to it from producers or the service. Instead, we sync
1120*6dbdd20aSAndroid Build Coastguard Worker   // the consumer and producer IPC streams for this test, to ensure that the
1121*6dbdd20aSAndroid Build Coastguard Worker   // producer_name_filter change has propagated.
1122*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->GetTraceStatsBlocking();  // sync consumer stream.
1123*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();                  // sync producer stream.
1124*6dbdd20aSAndroid Build Coastguard Worker 
1125*6dbdd20aSAndroid Build Coastguard Worker   // Emit a second trace event, this one should be included because
1126*6dbdd20aSAndroid Build Coastguard Worker   // the producer name filter was cleared.
1127*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "EventIncluded");
1128*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
1129*6dbdd20aSAndroid Build Coastguard Worker 
1130*6dbdd20aSAndroid Build Coastguard Worker   // Verify that only the second event is in the trace data.
1131*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
1132*6dbdd20aSAndroid Build Coastguard Worker   std::string trace(raw_trace.data(), raw_trace.size());
1133*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("EventFilteredOut")));
1134*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, HasSubstr("EventIncluded"));
1135*6dbdd20aSAndroid Build Coastguard Worker }
1136*6dbdd20aSAndroid Build Coastguard Worker 
1137*6dbdd20aSAndroid Build Coastguard Worker // This is a build-only regression test that checks you can have a track event
1138*6dbdd20aSAndroid Build Coastguard Worker // inside a template.
1139*6dbdd20aSAndroid Build Coastguard Worker template <typename T>
TestTrackEventInsideTemplate(T)1140*6dbdd20aSAndroid Build Coastguard Worker void TestTrackEventInsideTemplate(T) {
1141*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("cat", "Name");
1142*6dbdd20aSAndroid Build Coastguard Worker }
1143*6dbdd20aSAndroid Build Coastguard Worker 
1144*6dbdd20aSAndroid Build Coastguard Worker // This is a build-only regression test that checks you can specify the tracing
1145*6dbdd20aSAndroid Build Coastguard Worker // category as a template argument.
1146*6dbdd20aSAndroid Build Coastguard Worker constexpr const char kTestCategory[] = "foo";
1147*6dbdd20aSAndroid Build Coastguard Worker template <const char* category>
TestCategoryAsTemplateParameter()1148*6dbdd20aSAndroid Build Coastguard Worker void TestCategoryAsTemplateParameter() {
1149*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN(category, "Name");
1150*6dbdd20aSAndroid Build Coastguard Worker }
1151*6dbdd20aSAndroid Build Coastguard Worker 
1152*6dbdd20aSAndroid Build Coastguard Worker // Sleep for |nano_seconds| in a way that this duration is counted in
1153*6dbdd20aSAndroid Build Coastguard Worker // thread_time. i.e. sleep without using OS's sleep method, which blocks the
1154*6dbdd20aSAndroid Build Coastguard Worker // thread and OS doesn't schedule it until expected wake-up-time.
SpinForThreadTimeNanos(int64_t nano_seconds)1155*6dbdd20aSAndroid Build Coastguard Worker void SpinForThreadTimeNanos(int64_t nano_seconds) {
1156*6dbdd20aSAndroid Build Coastguard Worker   auto time_now = perfetto::base::GetThreadCPUTimeNs().count();
1157*6dbdd20aSAndroid Build Coastguard Worker   auto goal_time = time_now + nano_seconds;
1158*6dbdd20aSAndroid Build Coastguard Worker   while (perfetto::base::GetThreadCPUTimeNs().count() < goal_time) {
1159*6dbdd20aSAndroid Build Coastguard Worker   }
1160*6dbdd20aSAndroid Build Coastguard Worker }
1161*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventTimestampUnitAbsolute)1162*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventTimestampUnitAbsolute) {
1163*6dbdd20aSAndroid Build Coastguard Worker   for (auto unit_multiplier : {1u, 1000u}) {
1164*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
1165*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.set_disable_incremental_timestamps(true);
1166*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.set_timestamp_unit_multiplier(unit_multiplier);
1167*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"}, te_cfg);
1168*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
1169*6dbdd20aSAndroid Build Coastguard Worker     int64_t t_before = static_cast<int64_t>(TrackEventInternal::GetTimeNs());
1170*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "Event1");
1171*6dbdd20aSAndroid Build Coastguard Worker     SpinForThreadTimeNanos(1000000);
1172*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "Event2");
1173*6dbdd20aSAndroid Build Coastguard Worker     SpinForThreadTimeNanos(1000000);
1174*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "Event3");
1175*6dbdd20aSAndroid Build Coastguard Worker     int64_t t_after = static_cast<int64_t>(TrackEventInternal::GetTimeNs());
1176*6dbdd20aSAndroid Build Coastguard Worker     auto trace = StopSessionAndReturnParsedTrace(tracing_session);
1177*6dbdd20aSAndroid Build Coastguard Worker     std::unordered_map<std::string, int64_t> event_map;
1178*6dbdd20aSAndroid Build Coastguard Worker     bool found_absolute_clock = false;
1179*6dbdd20aSAndroid Build Coastguard Worker     for (const auto& packet : trace.packet()) {
1180*6dbdd20aSAndroid Build Coastguard Worker       if (packet.has_interned_data()) {
1181*6dbdd20aSAndroid Build Coastguard Worker         if (packet.interned_data().event_names().size() == 1) {
1182*6dbdd20aSAndroid Build Coastguard Worker           auto& event_name = packet.interned_data().event_names()[0].name();
1183*6dbdd20aSAndroid Build Coastguard Worker           event_map[event_name] = static_cast<int64_t>(packet.timestamp());
1184*6dbdd20aSAndroid Build Coastguard Worker         }
1185*6dbdd20aSAndroid Build Coastguard Worker       }
1186*6dbdd20aSAndroid Build Coastguard Worker       if (packet.has_trace_packet_defaults()) {
1187*6dbdd20aSAndroid Build Coastguard Worker         auto clock_id = packet.trace_packet_defaults().timestamp_clock_id();
1188*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(unit_multiplier == 1
1189*6dbdd20aSAndroid Build Coastguard Worker                       ? static_cast<uint32_t>(TrackEventInternal::GetClockId())
1190*6dbdd20aSAndroid Build Coastguard Worker                       : TrackEventIncrementalState::kClockIdAbsolute,
1191*6dbdd20aSAndroid Build Coastguard Worker                   clock_id);
1192*6dbdd20aSAndroid Build Coastguard Worker         if (packet.has_clock_snapshot()) {
1193*6dbdd20aSAndroid Build Coastguard Worker           for (auto& clock : packet.clock_snapshot().clocks()) {
1194*6dbdd20aSAndroid Build Coastguard Worker             if (clock.clock_id() ==
1195*6dbdd20aSAndroid Build Coastguard Worker                 TrackEventIncrementalState::kClockIdAbsolute) {
1196*6dbdd20aSAndroid Build Coastguard Worker               found_absolute_clock = true;
1197*6dbdd20aSAndroid Build Coastguard Worker               EXPECT_EQ(unit_multiplier, clock.unit_multiplier_ns());
1198*6dbdd20aSAndroid Build Coastguard Worker               EXPECT_FALSE(clock.is_incremental());
1199*6dbdd20aSAndroid Build Coastguard Worker             }
1200*6dbdd20aSAndroid Build Coastguard Worker           }
1201*6dbdd20aSAndroid Build Coastguard Worker         }
1202*6dbdd20aSAndroid Build Coastguard Worker       }
1203*6dbdd20aSAndroid Build Coastguard Worker     }
1204*6dbdd20aSAndroid Build Coastguard Worker 
1205*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ((unit_multiplier == 1000), found_absolute_clock);
1206*6dbdd20aSAndroid Build Coastguard Worker 
1207*6dbdd20aSAndroid Build Coastguard Worker     auto e1_t = event_map.at("Event1");
1208*6dbdd20aSAndroid Build Coastguard Worker     auto e2_t = event_map.at("Event2");
1209*6dbdd20aSAndroid Build Coastguard Worker     auto e3_t = event_map.at("Event3");
1210*6dbdd20aSAndroid Build Coastguard Worker 
1211*6dbdd20aSAndroid Build Coastguard Worker     int64_t min_delta = 1000000 / unit_multiplier;
1212*6dbdd20aSAndroid Build Coastguard Worker     int64_t max_delta = (t_after - t_before) / unit_multiplier;
1213*6dbdd20aSAndroid Build Coastguard Worker 
1214*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_LE(t_before / unit_multiplier, e1_t);
1215*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_LE(e3_t, t_after / unit_multiplier);
1216*6dbdd20aSAndroid Build Coastguard Worker 
1217*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_GE(e2_t - e1_t, min_delta);
1218*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_GE(e3_t - e2_t, min_delta);
1219*6dbdd20aSAndroid Build Coastguard Worker 
1220*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_LE(e2_t - e1_t, max_delta);
1221*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_LE(e3_t - e2_t, max_delta);
1222*6dbdd20aSAndroid Build Coastguard Worker   }
1223*6dbdd20aSAndroid Build Coastguard Worker }
1224*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventTimestampUnitIncremental)1225*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventTimestampUnitIncremental) {
1226*6dbdd20aSAndroid Build Coastguard Worker   for (auto unit_multiplier : {1u, 1000u}) {
1227*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
1228*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.set_enable_thread_time_sampling(true);
1229*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.set_timestamp_unit_multiplier(unit_multiplier);
1230*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"}, te_cfg);
1231*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
1232*6dbdd20aSAndroid Build Coastguard Worker     SpinForThreadTimeNanos(1000000);
1233*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "Event1");
1234*6dbdd20aSAndroid Build Coastguard Worker     SpinForThreadTimeNanos(1000000);
1235*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "Event2");
1236*6dbdd20aSAndroid Build Coastguard Worker     SpinForThreadTimeNanos(1000000);
1237*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "Event3");
1238*6dbdd20aSAndroid Build Coastguard Worker     auto trace = StopSessionAndReturnParsedTrace(tracing_session);
1239*6dbdd20aSAndroid Build Coastguard Worker     struct TimeInfo {
1240*6dbdd20aSAndroid Build Coastguard Worker       int64_t timestamp;
1241*6dbdd20aSAndroid Build Coastguard Worker       int64_t thread_time;
1242*6dbdd20aSAndroid Build Coastguard Worker     };
1243*6dbdd20aSAndroid Build Coastguard Worker     std::unordered_map<std::string, TimeInfo> event_map;
1244*6dbdd20aSAndroid Build Coastguard Worker     for (const auto& packet : trace.packet()) {
1245*6dbdd20aSAndroid Build Coastguard Worker       if (packet.has_interned_data()) {
1246*6dbdd20aSAndroid Build Coastguard Worker         if (packet.interned_data().event_names().size() == 1) {
1247*6dbdd20aSAndroid Build Coastguard Worker           auto& event_name = packet.interned_data().event_names()[0].name();
1248*6dbdd20aSAndroid Build Coastguard Worker           if (packet.has_track_event() &&
1249*6dbdd20aSAndroid Build Coastguard Worker               packet.track_event().extra_counter_values().size() > 0) {
1250*6dbdd20aSAndroid Build Coastguard Worker             auto thread_time = packet.track_event().extra_counter_values()[0];
1251*6dbdd20aSAndroid Build Coastguard Worker             event_map[event_name] = {static_cast<int64_t>(packet.timestamp()),
1252*6dbdd20aSAndroid Build Coastguard Worker                                      thread_time};
1253*6dbdd20aSAndroid Build Coastguard Worker           }
1254*6dbdd20aSAndroid Build Coastguard Worker         }
1255*6dbdd20aSAndroid Build Coastguard Worker       }
1256*6dbdd20aSAndroid Build Coastguard Worker     }
1257*6dbdd20aSAndroid Build Coastguard Worker     int min_delta = 1000 * (unit_multiplier == 1 ? 1000 : 1);
1258*6dbdd20aSAndroid Build Coastguard Worker 
1259*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(0, event_map.at("Event1").timestamp);
1260*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_GT(event_map.at("Event2").timestamp, min_delta);
1261*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_GT(event_map.at("Event3").timestamp, min_delta);
1262*6dbdd20aSAndroid Build Coastguard Worker 
1263*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_GT(event_map.at("Event2").thread_time, min_delta);
1264*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_GT(event_map.at("Event3").thread_time, min_delta);
1265*6dbdd20aSAndroid Build Coastguard Worker   }
1266*6dbdd20aSAndroid Build Coastguard Worker }
1267*6dbdd20aSAndroid Build Coastguard Worker 
1268*6dbdd20aSAndroid Build Coastguard Worker // Tests that we don't accumulate error when using incremental timestamps with
1269*6dbdd20aSAndroid Build Coastguard Worker // timestamp unit multiplier.
TEST_P(PerfettoApiTest,TrackEventTimestampIncrementalAccumulatedError)1270*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventTimestampIncrementalAccumulatedError) {
1271*6dbdd20aSAndroid Build Coastguard Worker   constexpr uint64_t kUnitMultiplier = 100000;
1272*6dbdd20aSAndroid Build Coastguard Worker   constexpr uint64_t kNumberOfEvents = 1000;
1273*6dbdd20aSAndroid Build Coastguard Worker   constexpr uint64_t kTimeBetweenEventsNs = 50000;
1274*6dbdd20aSAndroid Build Coastguard Worker 
1275*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TrackEventConfig te_cfg;
1276*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.set_timestamp_unit_multiplier(kUnitMultiplier);
1277*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"}, te_cfg);
1278*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1279*6dbdd20aSAndroid Build Coastguard Worker   auto start = perfetto::TrackEvent::GetTraceTimeNs();
1280*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Start");
1281*6dbdd20aSAndroid Build Coastguard Worker   for (uint64_t i = 0; i < kNumberOfEvents; ++i) {
1282*6dbdd20aSAndroid Build Coastguard Worker     SpinForThreadTimeNanos(kTimeBetweenEventsNs);
1283*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "Event");
1284*6dbdd20aSAndroid Build Coastguard Worker   }
1285*6dbdd20aSAndroid Build Coastguard Worker   auto end = perfetto::TrackEvent::GetTraceTimeNs();
1286*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
1287*6dbdd20aSAndroid Build Coastguard Worker   uint64_t accumulated_timestamp = 0;
1288*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
1289*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_event()) {
1290*6dbdd20aSAndroid Build Coastguard Worker       accumulated_timestamp += packet.timestamp() * kUnitMultiplier;
1291*6dbdd20aSAndroid Build Coastguard Worker     }
1292*6dbdd20aSAndroid Build Coastguard Worker   }
1293*6dbdd20aSAndroid Build Coastguard Worker 
1294*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_GE(accumulated_timestamp, kNumberOfEvents * kTimeBetweenEventsNs);
1295*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_LE(accumulated_timestamp, end - start);
1296*6dbdd20aSAndroid Build Coastguard Worker }
1297*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEvent)1298*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEvent) {
1299*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
1300*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
1301*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1302*6dbdd20aSAndroid Build Coastguard Worker 
1303*6dbdd20aSAndroid Build Coastguard Worker   // Emit one complete track event.
1304*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "TestEvent");
1305*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("test");
1306*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Flush();
1307*6dbdd20aSAndroid Build Coastguard Worker 
1308*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->on_stop.Wait();
1309*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
1310*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_GE(raw_trace.size(), 0u);
1311*6dbdd20aSAndroid Build Coastguard Worker 
1312*6dbdd20aSAndroid Build Coastguard Worker   // Read back the trace, maintaining interning tables as we go.
1313*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace trace;
1314*6dbdd20aSAndroid Build Coastguard Worker   std::map<uint64_t, std::string> categories;
1315*6dbdd20aSAndroid Build Coastguard Worker   std::map<uint64_t, std::string> event_names;
1316*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
1317*6dbdd20aSAndroid Build Coastguard Worker 
1318*6dbdd20aSAndroid Build Coastguard Worker   auto now = perfetto::TrackEvent::GetTraceTimeNs();
1319*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
1320*6dbdd20aSAndroid Build Coastguard Worker     !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1321*6dbdd20aSAndroid Build Coastguard Worker   auto clock_id = perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
1322*6dbdd20aSAndroid Build Coastguard Worker #else
1323*6dbdd20aSAndroid Build Coastguard Worker   auto clock_id = perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC;
1324*6dbdd20aSAndroid Build Coastguard Worker #endif
1325*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(clock_id, perfetto::TrackEvent::GetTraceClockId());
1326*6dbdd20aSAndroid Build Coastguard Worker 
1327*6dbdd20aSAndroid Build Coastguard Worker   bool incremental_state_was_cleared = false;
1328*6dbdd20aSAndroid Build Coastguard Worker   bool begin_found = false;
1329*6dbdd20aSAndroid Build Coastguard Worker   bool end_found = false;
1330*6dbdd20aSAndroid Build Coastguard Worker   bool process_descriptor_found = false;
1331*6dbdd20aSAndroid Build Coastguard Worker   uint32_t sequence_id = 0;
1332*6dbdd20aSAndroid Build Coastguard Worker   int32_t cur_pid = perfetto::test::GetCurrentProcessId();
1333*6dbdd20aSAndroid Build Coastguard Worker   uint64_t recent_absolute_time_ns = 0;
1334*6dbdd20aSAndroid Build Coastguard Worker   bool found_incremental_clock = false;
1335*6dbdd20aSAndroid Build Coastguard Worker   constexpr auto kClockIdIncremental =
1336*6dbdd20aSAndroid Build Coastguard Worker       TrackEventIncrementalState::kClockIdIncremental;
1337*6dbdd20aSAndroid Build Coastguard Worker 
1338*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
1339*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_descriptor()) {
1340*6dbdd20aSAndroid Build Coastguard Worker       const auto& desc = packet.track_descriptor();
1341*6dbdd20aSAndroid Build Coastguard Worker       if (desc.has_process()) {
1342*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_FALSE(process_descriptor_found);
1343*6dbdd20aSAndroid Build Coastguard Worker         const auto& pd = desc.process();
1344*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(cur_pid, pd.pid());
1345*6dbdd20aSAndroid Build Coastguard Worker         process_descriptor_found = true;
1346*6dbdd20aSAndroid Build Coastguard Worker       }
1347*6dbdd20aSAndroid Build Coastguard Worker     }
1348*6dbdd20aSAndroid Build Coastguard Worker     if (packet.sequence_flags() &
1349*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
1350*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(packet.has_trace_packet_defaults());
1351*6dbdd20aSAndroid Build Coastguard Worker       incremental_state_was_cleared = true;
1352*6dbdd20aSAndroid Build Coastguard Worker       categories.clear();
1353*6dbdd20aSAndroid Build Coastguard Worker       event_names.clear();
1354*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(kClockIdIncremental,
1355*6dbdd20aSAndroid Build Coastguard Worker                 packet.trace_packet_defaults().timestamp_clock_id());
1356*6dbdd20aSAndroid Build Coastguard Worker     }
1357*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_clock_snapshot()) {
1358*6dbdd20aSAndroid Build Coastguard Worker       for (auto& clock : packet.clock_snapshot().clocks()) {
1359*6dbdd20aSAndroid Build Coastguard Worker         if (clock.is_incremental()) {
1360*6dbdd20aSAndroid Build Coastguard Worker           found_incremental_clock = true;
1361*6dbdd20aSAndroid Build Coastguard Worker           recent_absolute_time_ns = clock.timestamp();
1362*6dbdd20aSAndroid Build Coastguard Worker           EXPECT_EQ(kClockIdIncremental, clock.clock_id());
1363*6dbdd20aSAndroid Build Coastguard Worker         }
1364*6dbdd20aSAndroid Build Coastguard Worker       }
1365*6dbdd20aSAndroid Build Coastguard Worker     }
1366*6dbdd20aSAndroid Build Coastguard Worker 
1367*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
1368*6dbdd20aSAndroid Build Coastguard Worker       continue;
1369*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(
1370*6dbdd20aSAndroid Build Coastguard Worker         packet.sequence_flags() &
1371*6dbdd20aSAndroid Build Coastguard Worker         (perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED |
1372*6dbdd20aSAndroid Build Coastguard Worker          perfetto::protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE));
1373*6dbdd20aSAndroid Build Coastguard Worker     const auto& track_event = packet.track_event();
1374*6dbdd20aSAndroid Build Coastguard Worker 
1375*6dbdd20aSAndroid Build Coastguard Worker     // Make sure we only see track events on one sequence.
1376*6dbdd20aSAndroid Build Coastguard Worker     if (packet.trusted_packet_sequence_id()) {
1377*6dbdd20aSAndroid Build Coastguard Worker       if (!sequence_id)
1378*6dbdd20aSAndroid Build Coastguard Worker         sequence_id = packet.trusted_packet_sequence_id();
1379*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(sequence_id, packet.trusted_packet_sequence_id());
1380*6dbdd20aSAndroid Build Coastguard Worker     }
1381*6dbdd20aSAndroid Build Coastguard Worker 
1382*6dbdd20aSAndroid Build Coastguard Worker     // Update incremental state.
1383*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_interned_data()) {
1384*6dbdd20aSAndroid Build Coastguard Worker       const auto& interned_data = packet.interned_data();
1385*6dbdd20aSAndroid Build Coastguard Worker       for (const auto& it : interned_data.event_categories()) {
1386*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(categories.find(it.iid()), categories.end());
1387*6dbdd20aSAndroid Build Coastguard Worker         categories[it.iid()] = it.name();
1388*6dbdd20aSAndroid Build Coastguard Worker       }
1389*6dbdd20aSAndroid Build Coastguard Worker       for (const auto& it : interned_data.event_names()) {
1390*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(event_names.find(it.iid()), event_names.end());
1391*6dbdd20aSAndroid Build Coastguard Worker         event_names[it.iid()] = it.name();
1392*6dbdd20aSAndroid Build Coastguard Worker       }
1393*6dbdd20aSAndroid Build Coastguard Worker     }
1394*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(found_incremental_clock);
1395*6dbdd20aSAndroid Build Coastguard Worker     uint64_t absolute_timestamp = packet.timestamp() + recent_absolute_time_ns;
1396*6dbdd20aSAndroid Build Coastguard Worker     recent_absolute_time_ns = absolute_timestamp;
1397*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_GT(absolute_timestamp, 0u);
1398*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_LE(absolute_timestamp, now);
1399*6dbdd20aSAndroid Build Coastguard Worker     // Packet uses default (incremental) clock.
1400*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(packet.has_timestamp_clock_id());
1401*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.type() ==
1402*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN) {
1403*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(begin_found);
1404*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(track_event.category_iids().size(), 1u);
1405*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_GE(track_event.category_iids()[0], 1u);
1406*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("test", categories[track_event.category_iids()[0]]);
1407*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("TestEvent", event_names[track_event.name_iid()]);
1408*6dbdd20aSAndroid Build Coastguard Worker       begin_found = true;
1409*6dbdd20aSAndroid Build Coastguard Worker     } else if (track_event.type() ==
1410*6dbdd20aSAndroid Build Coastguard Worker                perfetto::protos::gen::TrackEvent::TYPE_SLICE_END) {
1411*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(end_found);
1412*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(track_event.category_iids().size(), 0u);
1413*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(0u, track_event.name_iid());
1414*6dbdd20aSAndroid Build Coastguard Worker       end_found = true;
1415*6dbdd20aSAndroid Build Coastguard Worker     }
1416*6dbdd20aSAndroid Build Coastguard Worker   }
1417*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(incremental_state_was_cleared);
1418*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(process_descriptor_found);
1419*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(begin_found);
1420*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(end_found);
1421*6dbdd20aSAndroid Build Coastguard Worker 
1422*6dbdd20aSAndroid Build Coastguard Worker   // Dummy instantiation of test templates.
1423*6dbdd20aSAndroid Build Coastguard Worker   TestTrackEventInsideTemplate(true);
1424*6dbdd20aSAndroid Build Coastguard Worker   TestCategoryAsTemplateParameter<kTestCategory>();
1425*6dbdd20aSAndroid Build Coastguard Worker }
1426*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventWithIncrementalTimestamp)1427*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventWithIncrementalTimestamp) {
1428*6dbdd20aSAndroid Build Coastguard Worker   for (auto disable_incremental_timestamps : {false, true}) {
1429*6dbdd20aSAndroid Build Coastguard Worker     // Create a new trace session.
1430*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
1431*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.set_disable_incremental_timestamps(disable_incremental_timestamps);
1432*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"bar"}, te_cfg);
1433*6dbdd20aSAndroid Build Coastguard Worker     constexpr auto kClockIdIncremental =
1434*6dbdd20aSAndroid Build Coastguard Worker         TrackEventIncrementalState::kClockIdIncremental;
1435*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
1436*6dbdd20aSAndroid Build Coastguard Worker 
1437*6dbdd20aSAndroid Build Coastguard Worker     std::map<uint64_t, std::string> event_names;
1438*6dbdd20aSAndroid Build Coastguard Worker 
1439*6dbdd20aSAndroid Build Coastguard Worker     auto empty_lambda = [](perfetto::EventContext) {};
1440*6dbdd20aSAndroid Build Coastguard Worker 
1441*6dbdd20aSAndroid Build Coastguard Worker     constexpr uint64_t kInstantEvent1Time = 92718891479583;
1442*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT(
1443*6dbdd20aSAndroid Build Coastguard Worker         "bar", "InstantEvent1",
1444*6dbdd20aSAndroid Build Coastguard Worker         perfetto::TraceTimestamp{kClockIdIncremental, kInstantEvent1Time},
1445*6dbdd20aSAndroid Build Coastguard Worker         empty_lambda);
1446*6dbdd20aSAndroid Build Coastguard Worker 
1447*6dbdd20aSAndroid Build Coastguard Worker     constexpr uint64_t kInstantEvent2Time = 92718891618959;
1448*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT(
1449*6dbdd20aSAndroid Build Coastguard Worker         "bar", "InstantEvent2",
1450*6dbdd20aSAndroid Build Coastguard Worker         perfetto::TraceTimestamp{kClockIdIncremental, kInstantEvent2Time},
1451*6dbdd20aSAndroid Build Coastguard Worker         empty_lambda);
1452*6dbdd20aSAndroid Build Coastguard Worker 
1453*6dbdd20aSAndroid Build Coastguard Worker     auto trace = StopSessionAndReturnParsedTrace(tracing_session);
1454*6dbdd20aSAndroid Build Coastguard Worker     uint64_t absolute_timestamp = 0;
1455*6dbdd20aSAndroid Build Coastguard Worker     uint64_t prv_timestamp = 0;
1456*6dbdd20aSAndroid Build Coastguard Worker     int event_count = 0;
1457*6dbdd20aSAndroid Build Coastguard Worker     // Go through the packets and add the timestamps of those packets that use
1458*6dbdd20aSAndroid Build Coastguard Worker     // the incremental clock - in order to get the absolute timestamps of the
1459*6dbdd20aSAndroid Build Coastguard Worker     // track events.
1460*6dbdd20aSAndroid Build Coastguard Worker 
1461*6dbdd20aSAndroid Build Coastguard Worker     uint64_t default_clock_id = 0;
1462*6dbdd20aSAndroid Build Coastguard Worker     bool is_incremental = false;
1463*6dbdd20aSAndroid Build Coastguard Worker 
1464*6dbdd20aSAndroid Build Coastguard Worker     for (const auto& packet : trace.packet()) {
1465*6dbdd20aSAndroid Build Coastguard Worker       if (!packet.has_track_event() && !packet.has_clock_snapshot())
1466*6dbdd20aSAndroid Build Coastguard Worker         continue;
1467*6dbdd20aSAndroid Build Coastguard Worker       if (packet.has_trace_packet_defaults()) {
1468*6dbdd20aSAndroid Build Coastguard Worker         auto& defaults = packet.trace_packet_defaults();
1469*6dbdd20aSAndroid Build Coastguard Worker         if (defaults.has_timestamp_clock_id()) {
1470*6dbdd20aSAndroid Build Coastguard Worker           default_clock_id = defaults.timestamp_clock_id();
1471*6dbdd20aSAndroid Build Coastguard Worker         }
1472*6dbdd20aSAndroid Build Coastguard Worker       }
1473*6dbdd20aSAndroid Build Coastguard Worker       if (packet.has_clock_snapshot()) {
1474*6dbdd20aSAndroid Build Coastguard Worker         for (auto& clock : packet.clock_snapshot().clocks()) {
1475*6dbdd20aSAndroid Build Coastguard Worker           if (clock.is_incremental()) {
1476*6dbdd20aSAndroid Build Coastguard Worker             is_incremental = true;
1477*6dbdd20aSAndroid Build Coastguard Worker             absolute_timestamp = clock.timestamp();
1478*6dbdd20aSAndroid Build Coastguard Worker             EXPECT_EQ(clock.clock_id(), kClockIdIncremental);
1479*6dbdd20aSAndroid Build Coastguard Worker             EXPECT_FALSE(disable_incremental_timestamps);
1480*6dbdd20aSAndroid Build Coastguard Worker           }
1481*6dbdd20aSAndroid Build Coastguard Worker         }
1482*6dbdd20aSAndroid Build Coastguard Worker       } else {
1483*6dbdd20aSAndroid Build Coastguard Worker         auto clock_id = packet.has_timestamp_clock_id()
1484*6dbdd20aSAndroid Build Coastguard Worker                             ? packet.timestamp_clock_id()
1485*6dbdd20aSAndroid Build Coastguard Worker                             : default_clock_id;
1486*6dbdd20aSAndroid Build Coastguard Worker         if (clock_id == kClockIdIncremental) {
1487*6dbdd20aSAndroid Build Coastguard Worker           absolute_timestamp = prv_timestamp + packet.timestamp();
1488*6dbdd20aSAndroid Build Coastguard Worker           EXPECT_FALSE(disable_incremental_timestamps);
1489*6dbdd20aSAndroid Build Coastguard Worker         } else {
1490*6dbdd20aSAndroid Build Coastguard Worker           absolute_timestamp = packet.timestamp();
1491*6dbdd20aSAndroid Build Coastguard Worker           EXPECT_TRUE(disable_incremental_timestamps);
1492*6dbdd20aSAndroid Build Coastguard Worker         }
1493*6dbdd20aSAndroid Build Coastguard Worker       }
1494*6dbdd20aSAndroid Build Coastguard Worker       prv_timestamp = absolute_timestamp;
1495*6dbdd20aSAndroid Build Coastguard Worker 
1496*6dbdd20aSAndroid Build Coastguard Worker       if (packet.sequence_flags() & perfetto::protos::pbzero::TracePacket::
1497*6dbdd20aSAndroid Build Coastguard Worker                                         SEQ_INCREMENTAL_STATE_CLEARED) {
1498*6dbdd20aSAndroid Build Coastguard Worker         event_names.clear();
1499*6dbdd20aSAndroid Build Coastguard Worker       }
1500*6dbdd20aSAndroid Build Coastguard Worker 
1501*6dbdd20aSAndroid Build Coastguard Worker       // Update incremental state.
1502*6dbdd20aSAndroid Build Coastguard Worker       if (packet.has_interned_data()) {
1503*6dbdd20aSAndroid Build Coastguard Worker         const auto& interned_data = packet.interned_data();
1504*6dbdd20aSAndroid Build Coastguard Worker         for (const auto& it : interned_data.event_names()) {
1505*6dbdd20aSAndroid Build Coastguard Worker           EXPECT_EQ(event_names.find(it.iid()), event_names.end());
1506*6dbdd20aSAndroid Build Coastguard Worker           event_names[it.iid()] = it.name();
1507*6dbdd20aSAndroid Build Coastguard Worker         }
1508*6dbdd20aSAndroid Build Coastguard Worker       }
1509*6dbdd20aSAndroid Build Coastguard Worker 
1510*6dbdd20aSAndroid Build Coastguard Worker       if (event_names[packet.track_event().name_iid()] == "InstantEvent1") {
1511*6dbdd20aSAndroid Build Coastguard Worker         event_count++;
1512*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(absolute_timestamp, kInstantEvent1Time);
1513*6dbdd20aSAndroid Build Coastguard Worker       } else if (event_names[packet.track_event().name_iid()] ==
1514*6dbdd20aSAndroid Build Coastguard Worker                  "InstantEvent2") {
1515*6dbdd20aSAndroid Build Coastguard Worker         event_count++;
1516*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(absolute_timestamp, kInstantEvent2Time);
1517*6dbdd20aSAndroid Build Coastguard Worker       }
1518*6dbdd20aSAndroid Build Coastguard Worker     }
1519*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_NE(is_incremental, disable_incremental_timestamps);
1520*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(event_count, 2);
1521*6dbdd20aSAndroid Build Coastguard Worker   }
1522*6dbdd20aSAndroid Build Coastguard Worker }
1523*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventCategories)1524*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventCategories) {
1525*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
1526*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"bar"});
1527*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1528*6dbdd20aSAndroid Build Coastguard Worker 
1529*6dbdd20aSAndroid Build Coastguard Worker   // Emit some track events.
1530*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "NotEnabled");
1531*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
1532*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "Enabled");
1533*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("bar");
1534*6dbdd20aSAndroid Build Coastguard Worker 
1535*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
1536*6dbdd20aSAndroid Build Coastguard Worker   std::string trace(raw_trace.data(), raw_trace.size());
1537*6dbdd20aSAndroid Build Coastguard Worker   // TODO(skyostil): Come up with a nicer way to verify trace contents.
1538*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, HasSubstr("Enabled"));
1539*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("NotEnabled")));
1540*6dbdd20aSAndroid Build Coastguard Worker }
1541*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ClearIncrementalState)1542*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ClearIncrementalState) {
1543*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceDescriptor dsd;
1544*6dbdd20aSAndroid Build Coastguard Worker   dsd.set_name("incr_data_source");
1545*6dbdd20aSAndroid Build Coastguard Worker   TestIncrementalDataSource::Register(dsd);
1546*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
1547*6dbdd20aSAndroid Build Coastguard Worker 
1548*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config with an incremental state clearing period.
1549*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
1550*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
1551*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
1552*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1553*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("incr_data_source");
1554*6dbdd20aSAndroid Build Coastguard Worker   auto* is_cfg = cfg.mutable_incremental_state_config();
1555*6dbdd20aSAndroid Build Coastguard Worker   is_cfg->set_clear_period_ms(10);
1556*6dbdd20aSAndroid Build Coastguard Worker 
1557*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
1558*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
1559*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1560*6dbdd20aSAndroid Build Coastguard Worker 
1561*6dbdd20aSAndroid Build Coastguard Worker   // Observe at least 5 incremental state resets.
1562*6dbdd20aSAndroid Build Coastguard Worker   constexpr size_t kMaxLoops = 100;
1563*6dbdd20aSAndroid Build Coastguard Worker   size_t loops = 0;
1564*6dbdd20aSAndroid Build Coastguard Worker   size_t times_cleared = 0;
1565*6dbdd20aSAndroid Build Coastguard Worker   while (times_cleared < 5) {
1566*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_LT(loops++, kMaxLoops);
1567*6dbdd20aSAndroid Build Coastguard Worker     TestIncrementalDataSource::Trace(
1568*6dbdd20aSAndroid Build Coastguard Worker         [&](TestIncrementalDataSource::TraceContext ctx) {
1569*6dbdd20aSAndroid Build Coastguard Worker           auto* incr_state = ctx.GetIncrementalState();
1570*6dbdd20aSAndroid Build Coastguard Worker           if (!incr_state->flag) {
1571*6dbdd20aSAndroid Build Coastguard Worker             incr_state->flag = true;
1572*6dbdd20aSAndroid Build Coastguard Worker             times_cleared++;
1573*6dbdd20aSAndroid Build Coastguard Worker           }
1574*6dbdd20aSAndroid Build Coastguard Worker         });
1575*6dbdd20aSAndroid Build Coastguard Worker     std::this_thread::sleep_for(std::chrono::milliseconds(10));
1576*6dbdd20aSAndroid Build Coastguard Worker   }
1577*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
1578*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::TracingMuxerImplInternalsForTest::
1579*6dbdd20aSAndroid Build Coastguard Worker       ClearDataSourceTlsStateOnReset<TestIncrementalDataSource>();
1580*6dbdd20aSAndroid Build Coastguard Worker }
1581*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ClearIncrementalStateMultipleInstances)1582*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ClearIncrementalStateMultipleInstances) {
1583*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceDescriptor dsd;
1584*6dbdd20aSAndroid Build Coastguard Worker   dsd.set_name("incr_data_source");
1585*6dbdd20aSAndroid Build Coastguard Worker   TestIncrementalDataSource::Register(dsd);
1586*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
1587*6dbdd20aSAndroid Build Coastguard Worker 
1588*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config with an incremental state clearing period.
1589*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
1590*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
1591*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1592*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("incr_data_source");
1593*6dbdd20aSAndroid Build Coastguard Worker 
1594*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent cleared;
1595*6dbdd20aSAndroid Build Coastguard Worker   NiceMock<MockFunction<void(const perfetto::DataSourceBase::ClearIncrementalStateArgs&)>> cb;
1596*6dbdd20aSAndroid Build Coastguard Worker   ON_CALL(cb, Call). WillByDefault([&]{
1597*6dbdd20aSAndroid Build Coastguard Worker     cleared.Notify();
1598*6dbdd20aSAndroid Build Coastguard Worker   });
1599*6dbdd20aSAndroid Build Coastguard Worker   TestIncrementalDataSource::SetWillClearIncrementalStateCallback(cb.AsStdFunction());
1600*6dbdd20aSAndroid Build Coastguard Worker   auto cleanup = MakeCleanup([&] {
1601*6dbdd20aSAndroid Build Coastguard Worker     TestIncrementalDataSource::SetWillClearIncrementalStateCallback({});
1602*6dbdd20aSAndroid Build Coastguard Worker   });
1603*6dbdd20aSAndroid Build Coastguard Worker 
1604*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
1605*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
1606*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1607*6dbdd20aSAndroid Build Coastguard Worker 
1608*6dbdd20aSAndroid Build Coastguard Worker   auto* is_cfg = cfg.mutable_incremental_state_config();
1609*6dbdd20aSAndroid Build Coastguard Worker   is_cfg->set_clear_period_ms(10);
1610*6dbdd20aSAndroid Build Coastguard Worker 
1611*6dbdd20aSAndroid Build Coastguard Worker   // Create another tracing session that clear the incremental state
1612*6dbdd20aSAndroid Build Coastguard Worker   // periodically.
1613*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session2 = NewTrace(cfg);
1614*6dbdd20aSAndroid Build Coastguard Worker   tracing_session2->get()->StartBlocking();
1615*6dbdd20aSAndroid Build Coastguard Worker 
1616*6dbdd20aSAndroid Build Coastguard Worker   size_t count_instances = 0;
1617*6dbdd20aSAndroid Build Coastguard Worker   TestIncrementalDataSource::Trace(
1618*6dbdd20aSAndroid Build Coastguard Worker       [&](TestIncrementalDataSource::TraceContext ctx) {
1619*6dbdd20aSAndroid Build Coastguard Worker         count_instances++;
1620*6dbdd20aSAndroid Build Coastguard Worker         auto* incr_state = ctx.GetIncrementalState();
1621*6dbdd20aSAndroid Build Coastguard Worker         if (!incr_state->flag) {
1622*6dbdd20aSAndroid Build Coastguard Worker           incr_state->flag = true;
1623*6dbdd20aSAndroid Build Coastguard Worker         }
1624*6dbdd20aSAndroid Build Coastguard Worker       });
1625*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(count_instances, 2u);
1626*6dbdd20aSAndroid Build Coastguard Worker 
1627*6dbdd20aSAndroid Build Coastguard Worker   // Wait for two incremental state reset.
1628*6dbdd20aSAndroid Build Coastguard Worker   cleared.Reset();
1629*6dbdd20aSAndroid Build Coastguard Worker   cleared.Wait();
1630*6dbdd20aSAndroid Build Coastguard Worker   cleared.Reset();
1631*6dbdd20aSAndroid Build Coastguard Worker   cleared.Wait();
1632*6dbdd20aSAndroid Build Coastguard Worker 
1633*6dbdd20aSAndroid Build Coastguard Worker   std::vector<bool> instances_incremental_states;
1634*6dbdd20aSAndroid Build Coastguard Worker   TestIncrementalDataSource::Trace(
1635*6dbdd20aSAndroid Build Coastguard Worker       [&](TestIncrementalDataSource::TraceContext ctx) {
1636*6dbdd20aSAndroid Build Coastguard Worker         auto* incr_state = ctx.GetIncrementalState();
1637*6dbdd20aSAndroid Build Coastguard Worker         instances_incremental_states.push_back(incr_state->flag);
1638*6dbdd20aSAndroid Build Coastguard Worker       });
1639*6dbdd20aSAndroid Build Coastguard Worker 
1640*6dbdd20aSAndroid Build Coastguard Worker   // There are two instances.
1641*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(instances_incremental_states.size(), 2u);
1642*6dbdd20aSAndroid Build Coastguard Worker   // One was cleared.
1643*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(instances_incremental_states, Contains(false));
1644*6dbdd20aSAndroid Build Coastguard Worker   // The other one wasn't.
1645*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(instances_incremental_states, Contains(true));
1646*6dbdd20aSAndroid Build Coastguard Worker 
1647*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
1648*6dbdd20aSAndroid Build Coastguard Worker   tracing_session2->get()->StopBlocking();
1649*6dbdd20aSAndroid Build Coastguard Worker 
1650*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::TracingMuxerImplInternalsForTest::
1651*6dbdd20aSAndroid Build Coastguard Worker       ClearDataSourceTlsStateOnReset<TestIncrementalDataSource>();
1652*6dbdd20aSAndroid Build Coastguard Worker }
1653*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventRegistrationWithModule)1654*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventRegistrationWithModule) {
1655*6dbdd20aSAndroid Build Coastguard Worker   MockTracingMuxer muxer;
1656*6dbdd20aSAndroid Build Coastguard Worker 
1657*6dbdd20aSAndroid Build Coastguard Worker   // Each track event namespace registers its own data source.
1658*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Register();
1659*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(1u, muxer.data_sources.size());
1660*6dbdd20aSAndroid Build Coastguard Worker 
1661*6dbdd20aSAndroid Build Coastguard Worker   tracing_module::InitializeCategories();
1662*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(3u, muxer.data_sources.size());
1663*6dbdd20aSAndroid Build Coastguard Worker 
1664*6dbdd20aSAndroid Build Coastguard Worker   // Both data sources have the same name but distinct static data (i.e.,
1665*6dbdd20aSAndroid Build Coastguard Worker   // individual instance states).
1666*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("track_event", muxer.data_sources[0].dsd.name());
1667*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("track_event", muxer.data_sources[1].dsd.name());
1668*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("track_event", muxer.data_sources[2].dsd.name());
1669*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(muxer.data_sources[0].static_state,
1670*6dbdd20aSAndroid Build Coastguard Worker             muxer.data_sources[1].static_state);
1671*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(muxer.data_sources[0].static_state,
1672*6dbdd20aSAndroid Build Coastguard Worker             muxer.data_sources[2].static_state);
1673*6dbdd20aSAndroid Build Coastguard Worker }
1674*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventDescriptor)1675*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventDescriptor) {
1676*6dbdd20aSAndroid Build Coastguard Worker   MockTracingMuxer muxer;
1677*6dbdd20aSAndroid Build Coastguard Worker 
1678*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Register();
1679*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(1u, muxer.data_sources.size());
1680*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("track_event", muxer.data_sources[0].dsd.name());
1681*6dbdd20aSAndroid Build Coastguard Worker 
1682*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TrackEventDescriptor desc;
1683*6dbdd20aSAndroid Build Coastguard Worker   auto desc_raw = muxer.data_sources[0].dsd.track_event_descriptor_raw();
1684*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(desc.ParseFromArray(desc_raw.data(), desc_raw.size()));
1685*6dbdd20aSAndroid Build Coastguard Worker 
1686*6dbdd20aSAndroid Build Coastguard Worker   // Check that the advertised categories match PERFETTO_DEFINE_CATEGORIES (see
1687*6dbdd20aSAndroid Build Coastguard Worker   // above).
1688*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(7, desc.available_categories_size());
1689*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("test", desc.available_categories()[0].name());
1690*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("This is a test category",
1691*6dbdd20aSAndroid Build Coastguard Worker             desc.available_categories()[0].description());
1692*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("tag", desc.available_categories()[0].tags()[0]);
1693*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("foo", desc.available_categories()[1].name());
1694*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("bar", desc.available_categories()[2].name());
1695*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("cat", desc.available_categories()[3].name());
1696*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("slow", desc.available_categories()[3].tags()[0]);
1697*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("cat.verbose", desc.available_categories()[4].name());
1698*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("debug", desc.available_categories()[4].tags()[0]);
1699*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("cat-with-dashes", desc.available_categories()[5].name());
1700*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("disabled-by-default-cat", desc.available_categories()[6].name());
1701*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("slow", desc.available_categories()[6].tags()[0]);
1702*6dbdd20aSAndroid Build Coastguard Worker }
1703*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventSharedIncrementalState)1704*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventSharedIncrementalState) {
1705*6dbdd20aSAndroid Build Coastguard Worker   tracing_module::InitializeCategories();
1706*6dbdd20aSAndroid Build Coastguard Worker 
1707*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
1708*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
1709*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
1710*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
1711*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1712*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
1713*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
1714*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1715*6dbdd20aSAndroid Build Coastguard Worker 
1716*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::TrackEventIncrementalState* main_state = nullptr;
1717*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Trace(
1718*6dbdd20aSAndroid Build Coastguard Worker       [&main_state](perfetto::TrackEvent::TraceContext ctx) {
1719*6dbdd20aSAndroid Build Coastguard Worker         main_state = ctx.GetIncrementalState();
1720*6dbdd20aSAndroid Build Coastguard Worker       });
1721*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::TrackEventIncrementalState* module_state =
1722*6dbdd20aSAndroid Build Coastguard Worker       tracing_module::GetIncrementalState();
1723*6dbdd20aSAndroid Build Coastguard Worker 
1724*6dbdd20aSAndroid Build Coastguard Worker   // Both track event data sources should use the same incremental state (thanks
1725*6dbdd20aSAndroid Build Coastguard Worker   // to sharing TLS).
1726*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(nullptr, main_state);
1727*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(main_state, module_state);
1728*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
1729*6dbdd20aSAndroid Build Coastguard Worker }
1730*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventCategoriesWithModule)1731*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventCategoriesWithModule) {
1732*6dbdd20aSAndroid Build Coastguard Worker   // Check that categories defined in two different category registries are
1733*6dbdd20aSAndroid Build Coastguard Worker   // enabled and disabled correctly.
1734*6dbdd20aSAndroid Build Coastguard Worker   tracing_module::InitializeCategories();
1735*6dbdd20aSAndroid Build Coastguard Worker 
1736*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session. Only the "foo" category is enabled. It also
1737*6dbdd20aSAndroid Build Coastguard Worker   // exists both locally and in the existing module.
1738*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
1739*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1740*6dbdd20aSAndroid Build Coastguard Worker 
1741*6dbdd20aSAndroid Build Coastguard Worker   // Emit some track events locally and from the test module.
1742*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "FooEventFromMain");
1743*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
1744*6dbdd20aSAndroid Build Coastguard Worker   tracing_module::EmitTrackEvents();
1745*6dbdd20aSAndroid Build Coastguard Worker   tracing_module::EmitTrackEvents2();
1746*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "DisabledEventFromMain");
1747*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("bar");
1748*6dbdd20aSAndroid Build Coastguard Worker 
1749*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
1750*6dbdd20aSAndroid Build Coastguard Worker   std::string trace(raw_trace.data(), raw_trace.size());
1751*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, HasSubstr("FooEventFromMain"));
1752*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("DisabledEventFromMain")));
1753*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, HasSubstr("FooEventFromModule"));
1754*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("DisabledEventFromModule")));
1755*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, HasSubstr("FooEventFromModule2"));
1756*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("DisabledEventFromModule2")));
1757*6dbdd20aSAndroid Build Coastguard Worker 
1758*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace parsed_trace;
1759*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
1760*6dbdd20aSAndroid Build Coastguard Worker 
1761*6dbdd20aSAndroid Build Coastguard Worker   uint32_t sequence_id = 0;
1762*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : parsed_trace.packet()) {
1763*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
1764*6dbdd20aSAndroid Build Coastguard Worker       continue;
1765*6dbdd20aSAndroid Build Coastguard Worker 
1766*6dbdd20aSAndroid Build Coastguard Worker     // Make sure we only see track events on one sequence. This means all track
1767*6dbdd20aSAndroid Build Coastguard Worker     // event modules are sharing the same trace writer (by using the same TLS
1768*6dbdd20aSAndroid Build Coastguard Worker     // index).
1769*6dbdd20aSAndroid Build Coastguard Worker     if (packet.trusted_packet_sequence_id()) {
1770*6dbdd20aSAndroid Build Coastguard Worker       if (!sequence_id)
1771*6dbdd20aSAndroid Build Coastguard Worker         sequence_id = packet.trusted_packet_sequence_id();
1772*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(sequence_id, packet.trusted_packet_sequence_id());
1773*6dbdd20aSAndroid Build Coastguard Worker     }
1774*6dbdd20aSAndroid Build Coastguard Worker   }
1775*6dbdd20aSAndroid Build Coastguard Worker }
1776*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventNamespaces)1777*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventNamespaces) {
1778*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Register();
1779*6dbdd20aSAndroid Build Coastguard Worker   other_ns::TrackEvent::Register();
1780*6dbdd20aSAndroid Build Coastguard Worker   tracing_module::InitializeCategories();
1781*6dbdd20aSAndroid Build Coastguard Worker 
1782*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session =
1783*6dbdd20aSAndroid Build Coastguard Worker       NewTraceWithCategories({"test", "cat1", "extra", "other_ns"});
1784*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1785*6dbdd20aSAndroid Build Coastguard Worker 
1786*6dbdd20aSAndroid Build Coastguard Worker   // Default namespace.
1787*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "MainNamespaceEvent");
1788*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("test"));
1789*6dbdd20aSAndroid Build Coastguard Worker 
1790*6dbdd20aSAndroid Build Coastguard Worker   // Other namespace in a block scope.
1791*6dbdd20aSAndroid Build Coastguard Worker   {
1792*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_USE_CATEGORIES_FROM_NAMESPACE_SCOPED(other_ns);
1793*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT("other_ns", "OtherNamespaceEvent");
1794*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("other_ns"));
1795*6dbdd20aSAndroid Build Coastguard Worker   }
1796*6dbdd20aSAndroid Build Coastguard Worker 
1797*6dbdd20aSAndroid Build Coastguard Worker   // Back to the default namespace.
1798*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "MainNamespaceEvent2");
1799*6dbdd20aSAndroid Build Coastguard Worker 
1800*6dbdd20aSAndroid Build Coastguard Worker   // More namespaces defined in another module.
1801*6dbdd20aSAndroid Build Coastguard Worker   tracing_module::EmitTrackEventsFromAllNamespaces();
1802*6dbdd20aSAndroid Build Coastguard Worker 
1803*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
1804*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
1805*6dbdd20aSAndroid Build Coastguard Worker       slices,
1806*6dbdd20aSAndroid Build Coastguard Worker       ElementsAre("I:test.MainNamespaceEvent", "I:other_ns.OtherNamespaceEvent",
1807*6dbdd20aSAndroid Build Coastguard Worker                   "I:test.MainNamespaceEvent2",
1808*6dbdd20aSAndroid Build Coastguard Worker                   "B:cat1.DefaultNamespaceFromModule",
1809*6dbdd20aSAndroid Build Coastguard Worker                   "B:extra.ExtraNamespaceFromModule",
1810*6dbdd20aSAndroid Build Coastguard Worker                   "B:extra.OverrideNamespaceFromModule",
1811*6dbdd20aSAndroid Build Coastguard Worker                   "B:extra.DefaultNamespace", "B:cat1.DefaultNamespace"));
1812*6dbdd20aSAndroid Build Coastguard Worker }
1813*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventDynamicCategories)1814*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventDynamicCategories) {
1815*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
1816*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
1817*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
1818*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
1819*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1820*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
1821*6dbdd20aSAndroid Build Coastguard Worker 
1822*6dbdd20aSAndroid Build Coastguard Worker   // Session #1 enabled the "dynamic" category.
1823*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"dynamic"});
1824*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1825*6dbdd20aSAndroid Build Coastguard Worker 
1826*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("dynamic"));
1827*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic_2"));
1828*6dbdd20aSAndroid Build Coastguard Worker 
1829*6dbdd20aSAndroid Build Coastguard Worker   // Session #2 enables "dynamic_2".
1830*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session2 = NewTraceWithCategories({"dynamic_2"});
1831*6dbdd20aSAndroid Build Coastguard Worker   tracing_session2->get()->StartBlocking();
1832*6dbdd20aSAndroid Build Coastguard Worker 
1833*6dbdd20aSAndroid Build Coastguard Worker   // Test naming dynamic categories with std::string.
1834*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DynamicCategory dynamic{"dynamic"};
1835*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN(dynamic, "EventInDynamicCategory");
1836*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DynamicCategory dynamic_disabled{"dynamic_disabled"};
1837*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN(dynamic_disabled, "EventInDisabledDynamicCategory");
1838*6dbdd20aSAndroid Build Coastguard Worker 
1839*6dbdd20aSAndroid Build Coastguard Worker   // Test naming dynamic categories statically.
1840*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("dynamic", "EventInStaticallyNamedDynamicCategory");
1841*6dbdd20aSAndroid Build Coastguard Worker 
1842*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DynamicCategory dynamic_2{"dynamic_2"};
1843*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN(dynamic_2, "EventInSecondDynamicCategory");
1844*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("dynamic_2", "EventInSecondStaticallyNamedDynamicCategory");
1845*6dbdd20aSAndroid Build Coastguard Worker 
1846*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED(dynamic));
1847*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED(dynamic_2));
1848*6dbdd20aSAndroid Build Coastguard Worker 
1849*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([] {
1850*6dbdd20aSAndroid Build Coastguard Worker     // Make sure the category name can actually be computed at runtime.
1851*6dbdd20aSAndroid Build Coastguard Worker     std::string name = "dyn";
1852*6dbdd20aSAndroid Build Coastguard Worker     if (perfetto::base::GetThreadId())
1853*6dbdd20aSAndroid Build Coastguard Worker       name += "amic";
1854*6dbdd20aSAndroid Build Coastguard Worker     perfetto::DynamicCategory cat{name};
1855*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN(cat, "DynamicFromOtherThread");
1856*6dbdd20aSAndroid Build Coastguard Worker     perfetto::DynamicCategory cat2{"dynamic_disabled"};
1857*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN(cat2, "EventInDisabledDynamicCategory");
1858*6dbdd20aSAndroid Build Coastguard Worker   });
1859*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
1860*6dbdd20aSAndroid Build Coastguard Worker 
1861*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
1862*6dbdd20aSAndroid Build Coastguard Worker   std::string trace(raw_trace.data(), raw_trace.size());
1863*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, HasSubstr("EventInDynamicCategory"));
1864*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("EventInDisabledDynamicCategory")));
1865*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, HasSubstr("DynamicFromOtherThread"));
1866*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("EventInSecondDynamicCategory")));
1867*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, HasSubstr("EventInStaticallyNamedDynamicCategory"));
1868*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace,
1869*6dbdd20aSAndroid Build Coastguard Worker               Not(HasSubstr("EventInSecondStaticallyNamedDynamicCategory")));
1870*6dbdd20aSAndroid Build Coastguard Worker 
1871*6dbdd20aSAndroid Build Coastguard Worker   raw_trace = StopSessionAndReturnBytes(tracing_session2);
1872*6dbdd20aSAndroid Build Coastguard Worker   trace = std::string(raw_trace.data(), raw_trace.size());
1873*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("EventInDynamicCategory")));
1874*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("EventInDisabledDynamicCategory")));
1875*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("DynamicFromOtherThread")));
1876*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, HasSubstr("EventInSecondDynamicCategory"));
1877*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("EventInStaticallyNamedDynamicCategory")));
1878*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, HasSubstr("EventInSecondStaticallyNamedDynamicCategory"));
1879*6dbdd20aSAndroid Build Coastguard Worker }
1880*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventConcurrentSessions)1881*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventConcurrentSessions) {
1882*6dbdd20aSAndroid Build Coastguard Worker   // Check that categories that are enabled and disabled in two parallel tracing
1883*6dbdd20aSAndroid Build Coastguard Worker   // sessions don't interfere.
1884*6dbdd20aSAndroid Build Coastguard Worker 
1885*6dbdd20aSAndroid Build Coastguard Worker   // Session #1 enables the "foo" category.
1886*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
1887*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1888*6dbdd20aSAndroid Build Coastguard Worker 
1889*6dbdd20aSAndroid Build Coastguard Worker   // Session #2 enables the "bar" category.
1890*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session2 = NewTraceWithCategories({"bar"});
1891*6dbdd20aSAndroid Build Coastguard Worker   tracing_session2->get()->StartBlocking();
1892*6dbdd20aSAndroid Build Coastguard Worker 
1893*6dbdd20aSAndroid Build Coastguard Worker   // Emit some track events under both categories.
1894*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Session1_First");
1895*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
1896*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "Session2_First");
1897*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("bar");
1898*6dbdd20aSAndroid Build Coastguard Worker 
1899*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
1900*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Session1_Second");
1901*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
1902*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "Session2_Second");
1903*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("bar");
1904*6dbdd20aSAndroid Build Coastguard Worker 
1905*6dbdd20aSAndroid Build Coastguard Worker   tracing_session2->get()->StopBlocking();
1906*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Session1_Third");
1907*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
1908*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "Session2_Third");
1909*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("bar");
1910*6dbdd20aSAndroid Build Coastguard Worker 
1911*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
1912*6dbdd20aSAndroid Build Coastguard Worker   std::string trace(raw_trace.data(), raw_trace.size());
1913*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, HasSubstr("Session1_First"));
1914*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("Session1_Second")));
1915*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("Session1_Third")));
1916*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("Session2_First")));
1917*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("Session2_Second")));
1918*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace, Not(HasSubstr("Session2_Third")));
1919*6dbdd20aSAndroid Build Coastguard Worker 
1920*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace2 = tracing_session2->get()->ReadTraceBlocking();
1921*6dbdd20aSAndroid Build Coastguard Worker   std::string trace2(raw_trace2.data(), raw_trace2.size());
1922*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace2, Not(HasSubstr("Session1_First")));
1923*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace2, Not(HasSubstr("Session1_Second")));
1924*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace2, Not(HasSubstr("Session1_Third")));
1925*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace2, HasSubstr("Session2_First"));
1926*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace2, HasSubstr("Session2_Second"));
1927*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(trace2, Not(HasSubstr("Session2_Third")));
1928*6dbdd20aSAndroid Build Coastguard Worker }
1929*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventProcessAndThreadDescriptors)1930*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventProcessAndThreadDescriptors) {
1931*6dbdd20aSAndroid Build Coastguard Worker   // Thread and process descriptors can be set before tracing is enabled.
1932*6dbdd20aSAndroid Build Coastguard Worker   {
1933*6dbdd20aSAndroid Build Coastguard Worker     auto track = perfetto::ProcessTrack::Current();
1934*6dbdd20aSAndroid Build Coastguard Worker     auto desc = track.Serialize();
1935*6dbdd20aSAndroid Build Coastguard Worker     desc.set_name("hello.exe");
1936*6dbdd20aSAndroid Build Coastguard Worker     desc.mutable_chrome_process()->set_process_priority(1);
1937*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
1938*6dbdd20aSAndroid Build Coastguard Worker   }
1939*6dbdd20aSAndroid Build Coastguard Worker 
1940*6dbdd20aSAndroid Build Coastguard Worker   // Erased tracks shouldn't show up anywhere.
1941*6dbdd20aSAndroid Build Coastguard Worker   {
1942*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Track erased(1234u);
1943*6dbdd20aSAndroid Build Coastguard Worker     auto desc = erased.Serialize();
1944*6dbdd20aSAndroid Build Coastguard Worker     desc.set_name("ErasedTrack");
1945*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::SetTrackDescriptor(erased, std::move(desc));
1946*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::EraseTrackDescriptor(erased);
1947*6dbdd20aSAndroid Build Coastguard Worker   }
1948*6dbdd20aSAndroid Build Coastguard Worker 
1949*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
1950*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
1951*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
1952*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
1953*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
1954*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
1955*6dbdd20aSAndroid Build Coastguard Worker 
1956*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
1957*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
1958*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
1959*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "MainThreadEvent");
1960*6dbdd20aSAndroid Build Coastguard Worker 
1961*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([&] {
1962*6dbdd20aSAndroid Build Coastguard Worker     auto track = perfetto::ThreadTrack::Current();
1963*6dbdd20aSAndroid Build Coastguard Worker     auto desc = track.Serialize();
1964*6dbdd20aSAndroid Build Coastguard Worker     desc.set_name("TestThread");
1965*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
1966*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT("test", "ThreadEvent");
1967*6dbdd20aSAndroid Build Coastguard Worker   });
1968*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
1969*6dbdd20aSAndroid Build Coastguard Worker 
1970*6dbdd20aSAndroid Build Coastguard Worker   // Update the process descriptor while tracing is enabled. It should be
1971*6dbdd20aSAndroid Build Coastguard Worker   // immediately reflected in the trace.
1972*6dbdd20aSAndroid Build Coastguard Worker   {
1973*6dbdd20aSAndroid Build Coastguard Worker     auto track = perfetto::ProcessTrack::Current();
1974*6dbdd20aSAndroid Build Coastguard Worker     auto desc = track.Serialize();
1975*6dbdd20aSAndroid Build Coastguard Worker     desc.set_name("goodbye.exe");
1976*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
1977*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::Flush();
1978*6dbdd20aSAndroid Build Coastguard Worker   }
1979*6dbdd20aSAndroid Build Coastguard Worker 
1980*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
1981*6dbdd20aSAndroid Build Coastguard Worker 
1982*6dbdd20aSAndroid Build Coastguard Worker   // After tracing ends, setting the descriptor has no immediate effect.
1983*6dbdd20aSAndroid Build Coastguard Worker   {
1984*6dbdd20aSAndroid Build Coastguard Worker     auto track = perfetto::ProcessTrack::Current();
1985*6dbdd20aSAndroid Build Coastguard Worker     auto desc = track.Serialize();
1986*6dbdd20aSAndroid Build Coastguard Worker     desc.set_name("noop.exe");
1987*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
1988*6dbdd20aSAndroid Build Coastguard Worker   }
1989*6dbdd20aSAndroid Build Coastguard Worker 
1990*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
1991*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace trace;
1992*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
1993*6dbdd20aSAndroid Build Coastguard Worker 
1994*6dbdd20aSAndroid Build Coastguard Worker   std::vector<perfetto::protos::gen::TrackDescriptor> descs;
1995*6dbdd20aSAndroid Build Coastguard Worker   std::vector<perfetto::protos::gen::TrackDescriptor> thread_descs;
1996*6dbdd20aSAndroid Build Coastguard Worker   uint32_t main_thread_sequence = GetMainThreadPacketSequenceId(trace);
1997*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
1998*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_descriptor()) {
1999*6dbdd20aSAndroid Build Coastguard Worker       if (packet.trusted_packet_sequence_id() == main_thread_sequence) {
2000*6dbdd20aSAndroid Build Coastguard Worker         descs.push_back(packet.track_descriptor());
2001*6dbdd20aSAndroid Build Coastguard Worker       } else if (packet.track_descriptor().has_thread()) {
2002*6dbdd20aSAndroid Build Coastguard Worker         thread_descs.push_back(packet.track_descriptor());
2003*6dbdd20aSAndroid Build Coastguard Worker       }
2004*6dbdd20aSAndroid Build Coastguard Worker     }
2005*6dbdd20aSAndroid Build Coastguard Worker   }
2006*6dbdd20aSAndroid Build Coastguard Worker 
2007*6dbdd20aSAndroid Build Coastguard Worker   // The main thread records the initial process name as well as the one that's
2008*6dbdd20aSAndroid Build Coastguard Worker   // set during tracing. Additionally it records a thread descriptor for the
2009*6dbdd20aSAndroid Build Coastguard Worker   // main thread.
2010*6dbdd20aSAndroid Build Coastguard Worker 
2011*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(3u, descs.size());
2012*6dbdd20aSAndroid Build Coastguard Worker 
2013*6dbdd20aSAndroid Build Coastguard Worker   // Default track for the main thread.
2014*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(0, descs[0].process().pid());
2015*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(0, descs[0].thread().pid());
2016*6dbdd20aSAndroid Build Coastguard Worker 
2017*6dbdd20aSAndroid Build Coastguard Worker   // First process descriptor.
2018*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(0, descs[1].process().pid());
2019*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("hello.exe", descs[1].name());
2020*6dbdd20aSAndroid Build Coastguard Worker 
2021*6dbdd20aSAndroid Build Coastguard Worker   // Second process descriptor.
2022*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(0, descs[2].process().pid());
2023*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("goodbye.exe", descs[2].name());
2024*6dbdd20aSAndroid Build Coastguard Worker 
2025*6dbdd20aSAndroid Build Coastguard Worker   // The child thread records only its own thread descriptor (twice, since it
2026*6dbdd20aSAndroid Build Coastguard Worker   // was mutated).
2027*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(2u, thread_descs.size());
2028*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("TestThread", thread_descs[0].name());
2029*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(0, thread_descs[0].thread().pid());
2030*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(0, thread_descs[0].thread().tid());
2031*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("TestThread", thread_descs[1].name());
2032*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(0, thread_descs[1].thread().pid());
2033*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(0, thread_descs[1].thread().tid());
2034*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(0, descs[2].process().pid());
2035*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("goodbye.exe", descs[2].name());
2036*6dbdd20aSAndroid Build Coastguard Worker }
2037*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,CustomTrackDescriptor)2038*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, CustomTrackDescriptor) {
2039*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
2040*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
2041*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
2042*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
2043*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
2044*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
2045*6dbdd20aSAndroid Build Coastguard Worker 
2046*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2047*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
2048*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2049*6dbdd20aSAndroid Build Coastguard Worker 
2050*6dbdd20aSAndroid Build Coastguard Worker   auto track = perfetto::ProcessTrack::Current();
2051*6dbdd20aSAndroid Build Coastguard Worker   auto desc = track.Serialize();
2052*6dbdd20aSAndroid Build Coastguard Worker   desc.mutable_process()->set_process_name("testing.exe");
2053*6dbdd20aSAndroid Build Coastguard Worker   desc.mutable_thread()->set_tid(
2054*6dbdd20aSAndroid Build Coastguard Worker       static_cast<int32_t>(perfetto::base::GetThreadId()));
2055*6dbdd20aSAndroid Build Coastguard Worker   desc.mutable_chrome_process()->set_process_priority(123);
2056*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
2057*6dbdd20aSAndroid Build Coastguard Worker 
2058*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2059*6dbdd20aSAndroid Build Coastguard Worker 
2060*6dbdd20aSAndroid Build Coastguard Worker   uint32_t main_thread_sequence = GetMainThreadPacketSequenceId(trace);
2061*6dbdd20aSAndroid Build Coastguard Worker   bool found_desc = false;
2062*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2063*6dbdd20aSAndroid Build Coastguard Worker     if (packet.trusted_packet_sequence_id() != main_thread_sequence)
2064*6dbdd20aSAndroid Build Coastguard Worker       continue;
2065*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_descriptor()) {
2066*6dbdd20aSAndroid Build Coastguard Worker       auto td = packet.track_descriptor();
2067*6dbdd20aSAndroid Build Coastguard Worker       if (!td.has_process())
2068*6dbdd20aSAndroid Build Coastguard Worker         continue;
2069*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_NE(0, td.process().pid());
2070*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(td.has_chrome_process());
2071*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("testing.exe", td.process().process_name());
2072*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(123, td.chrome_process().process_priority());
2073*6dbdd20aSAndroid Build Coastguard Worker       found_desc = true;
2074*6dbdd20aSAndroid Build Coastguard Worker     }
2075*6dbdd20aSAndroid Build Coastguard Worker   }
2076*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_desc);
2077*6dbdd20aSAndroid Build Coastguard Worker }
2078*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventCustomTrack)2079*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventCustomTrack) {
2080*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2081*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"bar"});
2082*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2083*6dbdd20aSAndroid Build Coastguard Worker 
2084*6dbdd20aSAndroid Build Coastguard Worker   // Declare a custom track and give it a name.
2085*6dbdd20aSAndroid Build Coastguard Worker   uint64_t async_id = 123;
2086*6dbdd20aSAndroid Build Coastguard Worker 
2087*6dbdd20aSAndroid Build Coastguard Worker   {
2088*6dbdd20aSAndroid Build Coastguard Worker     auto track = perfetto::Track(async_id);
2089*6dbdd20aSAndroid Build Coastguard Worker     auto desc = track.Serialize();
2090*6dbdd20aSAndroid Build Coastguard Worker     desc.set_name("MyCustomTrack");
2091*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
2092*6dbdd20aSAndroid Build Coastguard Worker   }
2093*6dbdd20aSAndroid Build Coastguard Worker 
2094*6dbdd20aSAndroid Build Coastguard Worker   // Start events on one thread and end them on another.
2095*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "AsyncEvent", perfetto::Track(async_id), "debug_arg",
2096*6dbdd20aSAndroid Build Coastguard Worker                     123);
2097*6dbdd20aSAndroid Build Coastguard Worker 
2098*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "SubEvent", perfetto::Track(async_id),
2099*6dbdd20aSAndroid Build Coastguard Worker                     [](perfetto::EventContext) {});
2100*6dbdd20aSAndroid Build Coastguard Worker   const auto main_thread_track =
2101*6dbdd20aSAndroid Build Coastguard Worker       perfetto::Track(async_id, perfetto::ThreadTrack::Current());
2102*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([&] {
2103*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_END("bar", perfetto::Track(async_id));
2104*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_END("bar", perfetto::Track(async_id), "arg1", false, "arg2",
2105*6dbdd20aSAndroid Build Coastguard Worker                     true);
2106*6dbdd20aSAndroid Build Coastguard Worker     const auto thread_track =
2107*6dbdd20aSAndroid Build Coastguard Worker         perfetto::Track(async_id, perfetto::ThreadTrack::Current());
2108*6dbdd20aSAndroid Build Coastguard Worker     // Thread-scoped tracks will have different uuids on different thread even
2109*6dbdd20aSAndroid Build Coastguard Worker     // if the id matches.
2110*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_NE(main_thread_track.uuid, thread_track.uuid);
2111*6dbdd20aSAndroid Build Coastguard Worker   });
2112*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
2113*6dbdd20aSAndroid Build Coastguard Worker 
2114*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2115*6dbdd20aSAndroid Build Coastguard Worker 
2116*6dbdd20aSAndroid Build Coastguard Worker   // Check that the track uuids match on the begin and end events.
2117*6dbdd20aSAndroid Build Coastguard Worker   const auto track = perfetto::Track(async_id);
2118*6dbdd20aSAndroid Build Coastguard Worker   uint32_t main_thread_sequence = GetMainThreadPacketSequenceId(trace);
2119*6dbdd20aSAndroid Build Coastguard Worker   int event_count = 0;
2120*6dbdd20aSAndroid Build Coastguard Worker   bool found_descriptor = false;
2121*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2122*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_descriptor() &&
2123*6dbdd20aSAndroid Build Coastguard Worker         !packet.track_descriptor().has_process() &&
2124*6dbdd20aSAndroid Build Coastguard Worker         !packet.track_descriptor().has_thread()) {
2125*6dbdd20aSAndroid Build Coastguard Worker       auto td = packet.track_descriptor();
2126*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("MyCustomTrack", td.name());
2127*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(track.uuid, td.uuid());
2128*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(perfetto::ProcessTrack::Current().uuid, td.parent_uuid());
2129*6dbdd20aSAndroid Build Coastguard Worker       found_descriptor = true;
2130*6dbdd20aSAndroid Build Coastguard Worker       continue;
2131*6dbdd20aSAndroid Build Coastguard Worker     }
2132*6dbdd20aSAndroid Build Coastguard Worker 
2133*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
2134*6dbdd20aSAndroid Build Coastguard Worker       continue;
2135*6dbdd20aSAndroid Build Coastguard Worker     auto track_event = packet.track_event();
2136*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.type() ==
2137*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN) {
2138*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(main_thread_sequence, packet.trusted_packet_sequence_id());
2139*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(track.uuid, track_event.track_uuid());
2140*6dbdd20aSAndroid Build Coastguard Worker     } else {
2141*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_NE(main_thread_sequence, packet.trusted_packet_sequence_id());
2142*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(track.uuid, track_event.track_uuid());
2143*6dbdd20aSAndroid Build Coastguard Worker     }
2144*6dbdd20aSAndroid Build Coastguard Worker     event_count++;
2145*6dbdd20aSAndroid Build Coastguard Worker   }
2146*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_descriptor);
2147*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(4, event_count);
2148*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::EraseTrackDescriptor(track);
2149*6dbdd20aSAndroid Build Coastguard Worker }
2150*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventCustomNamedTrack)2151*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventCustomNamedTrack) {
2152*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2153*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"bar"});
2154*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2155*6dbdd20aSAndroid Build Coastguard Worker 
2156*6dbdd20aSAndroid Build Coastguard Worker   // Declare a custom track and give it a name.
2157*6dbdd20aSAndroid Build Coastguard Worker   uint64_t async_id = 123;
2158*6dbdd20aSAndroid Build Coastguard Worker 
2159*6dbdd20aSAndroid Build Coastguard Worker   // Start events on one thread and end them on another.
2160*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "AsyncEvent",
2161*6dbdd20aSAndroid Build Coastguard Worker                     perfetto::NamedTrack("MyCustomTrack", async_id),
2162*6dbdd20aSAndroid Build Coastguard Worker                     "debug_arg", 123);
2163*6dbdd20aSAndroid Build Coastguard Worker 
2164*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "SubEvent",
2165*6dbdd20aSAndroid Build Coastguard Worker                     perfetto::NamedTrack("MyCustomTrack", async_id),
2166*6dbdd20aSAndroid Build Coastguard Worker                     [](perfetto::EventContext) {});
2167*6dbdd20aSAndroid Build Coastguard Worker   const auto main_thread_track = perfetto::NamedTrack(
2168*6dbdd20aSAndroid Build Coastguard Worker       "MyCustomTrack", async_id, perfetto::ThreadTrack::Current());
2169*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([&] {
2170*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_END("bar", perfetto::NamedTrack("MyCustomTrack", async_id));
2171*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_END("bar", perfetto::NamedTrack("MyCustomTrack", async_id),
2172*6dbdd20aSAndroid Build Coastguard Worker                     "arg1", false, "arg2", true);
2173*6dbdd20aSAndroid Build Coastguard Worker     const auto thread_track = perfetto::NamedTrack(
2174*6dbdd20aSAndroid Build Coastguard Worker         "MyCustomTrack", async_id, perfetto::ThreadTrack::Current());
2175*6dbdd20aSAndroid Build Coastguard Worker     // Thread-scoped tracks will have different uuids on different thread even
2176*6dbdd20aSAndroid Build Coastguard Worker     // if the id matches.
2177*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_NE(main_thread_track.uuid, thread_track.uuid);
2178*6dbdd20aSAndroid Build Coastguard Worker   });
2179*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
2180*6dbdd20aSAndroid Build Coastguard Worker 
2181*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2182*6dbdd20aSAndroid Build Coastguard Worker 
2183*6dbdd20aSAndroid Build Coastguard Worker   // Check that the track uuids match on the begin and end events.
2184*6dbdd20aSAndroid Build Coastguard Worker   const auto track = perfetto::NamedTrack("MyCustomTrack", async_id);
2185*6dbdd20aSAndroid Build Coastguard Worker   uint32_t main_thread_sequence = GetMainThreadPacketSequenceId(trace);
2186*6dbdd20aSAndroid Build Coastguard Worker   int event_count = 0;
2187*6dbdd20aSAndroid Build Coastguard Worker   bool found_descriptor = false;
2188*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2189*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_descriptor() &&
2190*6dbdd20aSAndroid Build Coastguard Worker         !packet.track_descriptor().has_process() &&
2191*6dbdd20aSAndroid Build Coastguard Worker         !packet.track_descriptor().has_thread()) {
2192*6dbdd20aSAndroid Build Coastguard Worker       auto td = packet.track_descriptor();
2193*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("MyCustomTrack", td.static_name());
2194*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(track.uuid, td.uuid());
2195*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(perfetto::ProcessTrack::Current().uuid, td.parent_uuid());
2196*6dbdd20aSAndroid Build Coastguard Worker       found_descriptor = true;
2197*6dbdd20aSAndroid Build Coastguard Worker       continue;
2198*6dbdd20aSAndroid Build Coastguard Worker     }
2199*6dbdd20aSAndroid Build Coastguard Worker 
2200*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
2201*6dbdd20aSAndroid Build Coastguard Worker       continue;
2202*6dbdd20aSAndroid Build Coastguard Worker     auto track_event = packet.track_event();
2203*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.type() ==
2204*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN) {
2205*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(main_thread_sequence, packet.trusted_packet_sequence_id());
2206*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(track.uuid, track_event.track_uuid());
2207*6dbdd20aSAndroid Build Coastguard Worker     } else {
2208*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_NE(main_thread_sequence, packet.trusted_packet_sequence_id());
2209*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(track.uuid, track_event.track_uuid());
2210*6dbdd20aSAndroid Build Coastguard Worker     }
2211*6dbdd20aSAndroid Build Coastguard Worker     event_count++;
2212*6dbdd20aSAndroid Build Coastguard Worker   }
2213*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_descriptor);
2214*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(4, event_count);
2215*6dbdd20aSAndroid Build Coastguard Worker }
2216*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,CustomTrackDescriptorForParent)2217*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, CustomTrackDescriptorForParent) {
2218*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
2219*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
2220*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
2221*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
2222*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
2223*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
2224*6dbdd20aSAndroid Build Coastguard Worker 
2225*6dbdd20aSAndroid Build Coastguard Worker   // SetTrackDescriptor before starting the tracing session.
2226*6dbdd20aSAndroid Build Coastguard Worker   auto parent_track = perfetto::NamedTrack("MyCustomParent");
2227*6dbdd20aSAndroid Build Coastguard Worker   auto desc = parent_track.Serialize();
2228*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::SetTrackDescriptor(parent_track, std::move(desc));
2229*6dbdd20aSAndroid Build Coastguard Worker 
2230*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2231*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
2232*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2233*6dbdd20aSAndroid Build Coastguard Worker 
2234*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("bar", "AsyncEvent",
2235*6dbdd20aSAndroid Build Coastguard Worker                       perfetto::NamedTrack("MyCustomChild", 123, parent_track));
2236*6dbdd20aSAndroid Build Coastguard Worker 
2237*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2238*6dbdd20aSAndroid Build Coastguard Worker 
2239*6dbdd20aSAndroid Build Coastguard Worker   bool found_parent_desc = false;
2240*6dbdd20aSAndroid Build Coastguard Worker   bool found_child_desc = false;
2241*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2242*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_descriptor()) {
2243*6dbdd20aSAndroid Build Coastguard Worker       const auto& td = packet.track_descriptor();
2244*6dbdd20aSAndroid Build Coastguard Worker 
2245*6dbdd20aSAndroid Build Coastguard Worker       if (td.static_name() == "MyCustomParent") {
2246*6dbdd20aSAndroid Build Coastguard Worker         found_parent_desc = true;
2247*6dbdd20aSAndroid Build Coastguard Worker       } else if (td.static_name() == "MyCustomChild") {
2248*6dbdd20aSAndroid Build Coastguard Worker         found_child_desc = true;
2249*6dbdd20aSAndroid Build Coastguard Worker       }
2250*6dbdd20aSAndroid Build Coastguard Worker     }
2251*6dbdd20aSAndroid Build Coastguard Worker   }
2252*6dbdd20aSAndroid Build Coastguard Worker   // SetTrackDescriptor for the parent happened before the tracing session was
2253*6dbdd20aSAndroid Build Coastguard Worker   // running, but when emitting the child, the parent should be emitted as well.
2254*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_parent_desc);
2255*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_child_desc);
2256*6dbdd20aSAndroid Build Coastguard Worker }
2257*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventCustomTimestampClock)2258*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventCustomTimestampClock) {
2259*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2260*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2261*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2262*6dbdd20aSAndroid Build Coastguard Worker 
2263*6dbdd20aSAndroid Build Coastguard Worker   static constexpr perfetto::protos::pbzero::BuiltinClock kMyClockId =
2264*6dbdd20aSAndroid Build Coastguard Worker       static_cast<perfetto::protos::pbzero::BuiltinClock>(700);
2265*6dbdd20aSAndroid Build Coastguard Worker   static constexpr uint64_t kTimestamp = 12345678;
2266*6dbdd20aSAndroid Build Coastguard Worker 
2267*6dbdd20aSAndroid Build Coastguard Worker   // First emit a clock snapshot that maps our custom clock to regular trace
2268*6dbdd20aSAndroid Build Coastguard Worker   // time. Note that the clock snapshot should come before any events
2269*6dbdd20aSAndroid Build Coastguard Worker   // referencing that clock.
2270*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Trace([](perfetto::TrackEvent::TraceContext ctx) {
2271*6dbdd20aSAndroid Build Coastguard Worker     auto packet = ctx.NewTracePacket();
2272*6dbdd20aSAndroid Build Coastguard Worker     packet->set_timestamp_clock_id(
2273*6dbdd20aSAndroid Build Coastguard Worker         static_cast<uint32_t>(perfetto::TrackEvent::GetTraceClockId()));
2274*6dbdd20aSAndroid Build Coastguard Worker     packet->set_timestamp(perfetto::TrackEvent::GetTraceTimeNs());
2275*6dbdd20aSAndroid Build Coastguard Worker     auto* clock_snapshot = packet->set_clock_snapshot();
2276*6dbdd20aSAndroid Build Coastguard Worker     // First set the reference clock, i.e., the default trace clock in this
2277*6dbdd20aSAndroid Build Coastguard Worker     // case.
2278*6dbdd20aSAndroid Build Coastguard Worker     auto* clock = clock_snapshot->add_clocks();
2279*6dbdd20aSAndroid Build Coastguard Worker     clock->set_clock_id(
2280*6dbdd20aSAndroid Build Coastguard Worker         static_cast<uint32_t>(perfetto::TrackEvent::GetTraceClockId()));
2281*6dbdd20aSAndroid Build Coastguard Worker     clock->set_timestamp(perfetto::TrackEvent::GetTraceTimeNs());
2282*6dbdd20aSAndroid Build Coastguard Worker     // Then set the value of our reference clock at the same point in time. We
2283*6dbdd20aSAndroid Build Coastguard Worker     // pretend our clock is one second behind trace time.
2284*6dbdd20aSAndroid Build Coastguard Worker     clock = clock_snapshot->add_clocks();
2285*6dbdd20aSAndroid Build Coastguard Worker     clock->set_clock_id(kMyClockId);
2286*6dbdd20aSAndroid Build Coastguard Worker     clock->set_timestamp(kTimestamp + 1000000000ull);
2287*6dbdd20aSAndroid Build Coastguard Worker   });
2288*6dbdd20aSAndroid Build Coastguard Worker 
2289*6dbdd20aSAndroid Build Coastguard Worker   // Next emit a trace event with a custom timestamp and a custom clock.
2290*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "EventWithCustomTime",
2291*6dbdd20aSAndroid Build Coastguard Worker                       perfetto::TraceTimestamp{kMyClockId, kTimestamp});
2292*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "EventWithNormalTime");
2293*6dbdd20aSAndroid Build Coastguard Worker 
2294*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2295*6dbdd20aSAndroid Build Coastguard Worker 
2296*6dbdd20aSAndroid Build Coastguard Worker   // Check that both the clock id and the timestamp got written together with
2297*6dbdd20aSAndroid Build Coastguard Worker   // the packet. Note that we don't check the actual clock sync behavior here
2298*6dbdd20aSAndroid Build Coastguard Worker   // since that happens in the Trace Processor instead.
2299*6dbdd20aSAndroid Build Coastguard Worker   bool found_clock_snapshot = false;
2300*6dbdd20aSAndroid Build Coastguard Worker   bool found_event = false;
2301*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2302*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_clock_snapshot())
2303*6dbdd20aSAndroid Build Coastguard Worker       found_clock_snapshot = true;
2304*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event() || packet.timestamp() != kTimestamp)
2305*6dbdd20aSAndroid Build Coastguard Worker       continue;
2306*6dbdd20aSAndroid Build Coastguard Worker     found_event = true;
2307*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<uint32_t>(kMyClockId), packet.timestamp_clock_id());
2308*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(kTimestamp, packet.timestamp());
2309*6dbdd20aSAndroid Build Coastguard Worker   }
2310*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_clock_snapshot);
2311*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_event);
2312*6dbdd20aSAndroid Build Coastguard Worker }
2313*6dbdd20aSAndroid Build Coastguard Worker 
2314*6dbdd20aSAndroid Build Coastguard Worker // Only synchronous phases are supported for other threads. Hence disabled this
2315*6dbdd20aSAndroid Build Coastguard Worker // test.
2316*6dbdd20aSAndroid Build Coastguard Worker // TODO(b/261493947): fix or remove.
TEST_P(PerfettoApiTest,DISABLED_LegacyEventWithThreadOverride)2317*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, DISABLED_LegacyEventWithThreadOverride) {
2318*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2319*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
2320*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2321*6dbdd20aSAndroid Build Coastguard Worker 
2322*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0("cat", "Name", 1,
2323*6dbdd20aSAndroid Build Coastguard Worker                                                MyThreadId(456), MyTimestamp{0});
2324*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2325*6dbdd20aSAndroid Build Coastguard Worker 
2326*6dbdd20aSAndroid Build Coastguard Worker   // Check that we wrote a track descriptor for the custom thread track, and
2327*6dbdd20aSAndroid Build Coastguard Worker   // that the event was associated with that track.
2328*6dbdd20aSAndroid Build Coastguard Worker   const auto track = perfetto::ThreadTrack::ForThread(456);
2329*6dbdd20aSAndroid Build Coastguard Worker   bool found_descriptor = false;
2330*6dbdd20aSAndroid Build Coastguard Worker   bool found_event = false;
2331*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2332*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_descriptor() &&
2333*6dbdd20aSAndroid Build Coastguard Worker         packet.track_descriptor().has_thread()) {
2334*6dbdd20aSAndroid Build Coastguard Worker       auto td = packet.track_descriptor().thread();
2335*6dbdd20aSAndroid Build Coastguard Worker       if (td.tid() == 456) {
2336*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(track.uuid, packet.track_descriptor().uuid());
2337*6dbdd20aSAndroid Build Coastguard Worker         found_descriptor = true;
2338*6dbdd20aSAndroid Build Coastguard Worker       }
2339*6dbdd20aSAndroid Build Coastguard Worker     }
2340*6dbdd20aSAndroid Build Coastguard Worker 
2341*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
2342*6dbdd20aSAndroid Build Coastguard Worker       continue;
2343*6dbdd20aSAndroid Build Coastguard Worker     auto track_event = packet.track_event();
2344*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.legacy_event().phase() == TRACE_EVENT_PHASE_ASYNC_BEGIN) {
2345*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(0u, track_event.track_uuid());
2346*6dbdd20aSAndroid Build Coastguard Worker       found_event = true;
2347*6dbdd20aSAndroid Build Coastguard Worker     }
2348*6dbdd20aSAndroid Build Coastguard Worker   }
2349*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_descriptor);
2350*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_event);
2351*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::EraseTrackDescriptor(track);
2352*6dbdd20aSAndroid Build Coastguard Worker }
2353*6dbdd20aSAndroid Build Coastguard Worker 
2354*6dbdd20aSAndroid Build Coastguard Worker // Only synchronous phases are supported for other threads. Hence disabled this
2355*6dbdd20aSAndroid Build Coastguard Worker // test.
TEST_P(PerfettoApiTest,DISABLED_LegacyEventWithProcessOverride)2356*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, DISABLED_LegacyEventWithProcessOverride) {
2357*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2358*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
2359*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2360*6dbdd20aSAndroid Build Coastguard Worker 
2361*6dbdd20aSAndroid Build Coastguard Worker   // Note: there's no direct entrypoint for adding trace events for another
2362*6dbdd20aSAndroid Build Coastguard Worker   // process, so we're using the internal support macro here.
2363*6dbdd20aSAndroid Build Coastguard Worker   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(
2364*6dbdd20aSAndroid Build Coastguard Worker       TRACE_EVENT_PHASE_INSTANT, "cat", "Name", 0, MyThreadId{789},
2365*6dbdd20aSAndroid Build Coastguard Worker       MyTimestamp{0}, TRACE_EVENT_FLAG_HAS_PROCESS_ID);
2366*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2367*6dbdd20aSAndroid Build Coastguard Worker 
2368*6dbdd20aSAndroid Build Coastguard Worker   // Check that the event has a pid_override matching MyThread above.
2369*6dbdd20aSAndroid Build Coastguard Worker   bool found_event = false;
2370*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2371*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
2372*6dbdd20aSAndroid Build Coastguard Worker       continue;
2373*6dbdd20aSAndroid Build Coastguard Worker     auto track_event = packet.track_event();
2374*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.type() == perfetto::protos::gen::TrackEvent::TYPE_INSTANT) {
2375*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(789, track_event.legacy_event().pid_override());
2376*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(-1, track_event.legacy_event().tid_override());
2377*6dbdd20aSAndroid Build Coastguard Worker       found_event = true;
2378*6dbdd20aSAndroid Build Coastguard Worker     }
2379*6dbdd20aSAndroid Build Coastguard Worker   }
2380*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_event);
2381*6dbdd20aSAndroid Build Coastguard Worker }
2382*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackDescriptorWrittenBeforeEvent)2383*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackDescriptorWrittenBeforeEvent) {
2384*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2385*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"bar"});
2386*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2387*6dbdd20aSAndroid Build Coastguard Worker 
2388*6dbdd20aSAndroid Build Coastguard Worker   // Emit an event on a custom track.
2389*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("bar", "Event", perfetto::Track(8086));
2390*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2391*6dbdd20aSAndroid Build Coastguard Worker 
2392*6dbdd20aSAndroid Build Coastguard Worker   // Check that the descriptor was written before the event.
2393*6dbdd20aSAndroid Build Coastguard Worker   std::set<uint64_t> seen_descriptors;
2394*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2395*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_descriptor())
2396*6dbdd20aSAndroid Build Coastguard Worker       seen_descriptors.insert(packet.track_descriptor().uuid());
2397*6dbdd20aSAndroid Build Coastguard Worker 
2398*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
2399*6dbdd20aSAndroid Build Coastguard Worker       continue;
2400*6dbdd20aSAndroid Build Coastguard Worker     auto track_event = packet.track_event();
2401*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(seen_descriptors.find(track_event.track_uuid()) !=
2402*6dbdd20aSAndroid Build Coastguard Worker                 seen_descriptors.end());
2403*6dbdd20aSAndroid Build Coastguard Worker   }
2404*6dbdd20aSAndroid Build Coastguard Worker }
2405*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventCustomTrackAndTimestamp)2406*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventCustomTrackAndTimestamp) {
2407*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2408*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"bar"});
2409*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2410*6dbdd20aSAndroid Build Coastguard Worker 
2411*6dbdd20aSAndroid Build Coastguard Worker   // Custom track.
2412*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Track track(789);
2413*6dbdd20aSAndroid Build Coastguard Worker 
2414*6dbdd20aSAndroid Build Coastguard Worker   auto empty_lambda = [](perfetto::EventContext) {};
2415*6dbdd20aSAndroid Build Coastguard Worker   constexpr uint64_t kBeginEventTime = 10;
2416*6dbdd20aSAndroid Build Coastguard Worker   const MyTimestamp kEndEventTime{15};
2417*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "Event", track, kBeginEventTime, empty_lambda);
2418*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("bar", track, kEndEventTime, empty_lambda);
2419*6dbdd20aSAndroid Build Coastguard Worker 
2420*6dbdd20aSAndroid Build Coastguard Worker   constexpr uint64_t kInstantEventTime = 1;
2421*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("bar", "InstantEvent", track, kInstantEventTime,
2422*6dbdd20aSAndroid Build Coastguard Worker                       empty_lambda);
2423*6dbdd20aSAndroid Build Coastguard Worker 
2424*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2425*6dbdd20aSAndroid Build Coastguard Worker 
2426*6dbdd20aSAndroid Build Coastguard Worker   int event_count = 0;
2427*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2428*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
2429*6dbdd20aSAndroid Build Coastguard Worker       continue;
2430*6dbdd20aSAndroid Build Coastguard Worker 
2431*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(packet.timestamp_clock_id(),
2432*6dbdd20aSAndroid Build Coastguard Worker               static_cast<uint32_t>(perfetto::TrackEvent::GetTraceClockId()));
2433*6dbdd20aSAndroid Build Coastguard Worker     event_count++;
2434*6dbdd20aSAndroid Build Coastguard Worker     switch (packet.track_event().type()) {
2435*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN:
2436*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(packet.timestamp(), kBeginEventTime);
2437*6dbdd20aSAndroid Build Coastguard Worker         break;
2438*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_END:
2439*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(packet.timestamp(), kEndEventTime.ts);
2440*6dbdd20aSAndroid Build Coastguard Worker         break;
2441*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_INSTANT:
2442*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(packet.timestamp(), kInstantEventTime);
2443*6dbdd20aSAndroid Build Coastguard Worker         break;
2444*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_COUNTER:
2445*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_UNSPECIFIED:
2446*6dbdd20aSAndroid Build Coastguard Worker         ADD_FAILURE();
2447*6dbdd20aSAndroid Build Coastguard Worker     }
2448*6dbdd20aSAndroid Build Coastguard Worker   }
2449*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(event_count, 3);
2450*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::EraseTrackDescriptor(track);
2451*6dbdd20aSAndroid Build Coastguard Worker }
2452*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventCustomTrackAndTimestampNoLambda)2453*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventCustomTrackAndTimestampNoLambda) {
2454*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"bar"});
2455*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2456*6dbdd20aSAndroid Build Coastguard Worker 
2457*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Track track(789);
2458*6dbdd20aSAndroid Build Coastguard Worker 
2459*6dbdd20aSAndroid Build Coastguard Worker   constexpr uint64_t kBeginEventTime = 10;
2460*6dbdd20aSAndroid Build Coastguard Worker   constexpr uint64_t kEndEventTime = 15;
2461*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "Event", track, kBeginEventTime);
2462*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("bar", track, kEndEventTime);
2463*6dbdd20aSAndroid Build Coastguard Worker 
2464*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2465*6dbdd20aSAndroid Build Coastguard Worker 
2466*6dbdd20aSAndroid Build Coastguard Worker   int event_count = 0;
2467*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2468*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
2469*6dbdd20aSAndroid Build Coastguard Worker       continue;
2470*6dbdd20aSAndroid Build Coastguard Worker     event_count++;
2471*6dbdd20aSAndroid Build Coastguard Worker     switch (packet.track_event().type()) {
2472*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN:
2473*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(packet.timestamp(), kBeginEventTime);
2474*6dbdd20aSAndroid Build Coastguard Worker         break;
2475*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_SLICE_END:
2476*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(packet.timestamp(), kEndEventTime);
2477*6dbdd20aSAndroid Build Coastguard Worker         break;
2478*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_INSTANT:
2479*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_COUNTER:
2480*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::protos::gen::TrackEvent::TYPE_UNSPECIFIED:
2481*6dbdd20aSAndroid Build Coastguard Worker         ADD_FAILURE();
2482*6dbdd20aSAndroid Build Coastguard Worker     }
2483*6dbdd20aSAndroid Build Coastguard Worker   }
2484*6dbdd20aSAndroid Build Coastguard Worker 
2485*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(event_count, 2);
2486*6dbdd20aSAndroid Build Coastguard Worker }
2487*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventAnonymousCustomTrack)2488*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventAnonymousCustomTrack) {
2489*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2490*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"bar"});
2491*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2492*6dbdd20aSAndroid Build Coastguard Worker 
2493*6dbdd20aSAndroid Build Coastguard Worker   // Emit an async event without giving it an explicit descriptor.
2494*6dbdd20aSAndroid Build Coastguard Worker   uint64_t async_id = 4004;
2495*6dbdd20aSAndroid Build Coastguard Worker   auto track = perfetto::Track(async_id, perfetto::ThreadTrack::Current());
2496*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("bar", "AsyncEvent", track);
2497*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([&] { TRACE_EVENT_END("bar", track); });
2498*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
2499*6dbdd20aSAndroid Build Coastguard Worker 
2500*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2501*6dbdd20aSAndroid Build Coastguard Worker 
2502*6dbdd20aSAndroid Build Coastguard Worker   // Check that a descriptor for the track was emitted.
2503*6dbdd20aSAndroid Build Coastguard Worker   bool found_descriptor = false;
2504*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2505*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_descriptor() &&
2506*6dbdd20aSAndroid Build Coastguard Worker         !packet.track_descriptor().has_process() &&
2507*6dbdd20aSAndroid Build Coastguard Worker         !packet.track_descriptor().has_thread() &&
2508*6dbdd20aSAndroid Build Coastguard Worker         packet.track_descriptor().uuid() !=
2509*6dbdd20aSAndroid Build Coastguard Worker             perfetto::ThreadTrack::Current().uuid) {
2510*6dbdd20aSAndroid Build Coastguard Worker       auto td = packet.track_descriptor();
2511*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(track.uuid, td.uuid());
2512*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(perfetto::ThreadTrack::Current().uuid, td.parent_uuid());
2513*6dbdd20aSAndroid Build Coastguard Worker       found_descriptor = true;
2514*6dbdd20aSAndroid Build Coastguard Worker     }
2515*6dbdd20aSAndroid Build Coastguard Worker   }
2516*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_descriptor);
2517*6dbdd20aSAndroid Build Coastguard Worker }
2518*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventTypedArgs)2519*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventTypedArgs) {
2520*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2521*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2522*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2523*6dbdd20aSAndroid Build Coastguard Worker 
2524*6dbdd20aSAndroid Build Coastguard Worker   auto random_value = rand();
2525*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "EventWithTypedArg",
2526*6dbdd20aSAndroid Build Coastguard Worker                     [random_value](perfetto::EventContext ctx) {
2527*6dbdd20aSAndroid Build Coastguard Worker                       auto* log = ctx.event()->set_log_message();
2528*6dbdd20aSAndroid Build Coastguard Worker                       log->set_source_location_iid(1);
2529*6dbdd20aSAndroid Build Coastguard Worker                       log->set_body_iid(2);
2530*6dbdd20aSAndroid Build Coastguard Worker                       auto* dbg = ctx.event()->add_debug_annotations();
2531*6dbdd20aSAndroid Build Coastguard Worker                       dbg->set_name("random");
2532*6dbdd20aSAndroid Build Coastguard Worker                       dbg->set_int_value(random_value);
2533*6dbdd20aSAndroid Build Coastguard Worker                     });
2534*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2535*6dbdd20aSAndroid Build Coastguard Worker 
2536*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2537*6dbdd20aSAndroid Build Coastguard Worker 
2538*6dbdd20aSAndroid Build Coastguard Worker   bool found_args = false;
2539*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2540*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
2541*6dbdd20aSAndroid Build Coastguard Worker       continue;
2542*6dbdd20aSAndroid Build Coastguard Worker     const auto& track_event = packet.track_event();
2543*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.type() !=
2544*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN)
2545*6dbdd20aSAndroid Build Coastguard Worker       continue;
2546*6dbdd20aSAndroid Build Coastguard Worker 
2547*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(track_event.has_log_message());
2548*6dbdd20aSAndroid Build Coastguard Worker     const auto& log = track_event.log_message();
2549*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(1u, log.source_location_iid());
2550*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(2u, log.body_iid());
2551*6dbdd20aSAndroid Build Coastguard Worker 
2552*6dbdd20aSAndroid Build Coastguard Worker     const auto& dbg = track_event.debug_annotations()[0];
2553*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ("random", dbg.name());
2554*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(random_value, dbg.int_value());
2555*6dbdd20aSAndroid Build Coastguard Worker 
2556*6dbdd20aSAndroid Build Coastguard Worker     found_args = true;
2557*6dbdd20aSAndroid Build Coastguard Worker   }
2558*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_args);
2559*6dbdd20aSAndroid Build Coastguard Worker }
2560*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,InlineTrackEventTypedArgs_SimpleRepeated)2561*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, InlineTrackEventTypedArgs_SimpleRepeated) {
2562*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2563*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2564*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2565*6dbdd20aSAndroid Build Coastguard Worker 
2566*6dbdd20aSAndroid Build Coastguard Worker   std::vector<uint64_t> flow_ids_old{1, 2, 3};
2567*6dbdd20aSAndroid Build Coastguard Worker   std::vector<uint64_t> flow_ids{4, 5, 6};
2568*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "EventWithTypedArg",
2569*6dbdd20aSAndroid Build Coastguard Worker                     perfetto::protos::pbzero::TrackEvent::kFlowIdsOld,
2570*6dbdd20aSAndroid Build Coastguard Worker                     flow_ids_old,
2571*6dbdd20aSAndroid Build Coastguard Worker                     perfetto::protos::pbzero::TrackEvent::kFlowIds, flow_ids);
2572*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2573*6dbdd20aSAndroid Build Coastguard Worker 
2574*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2575*6dbdd20aSAndroid Build Coastguard Worker 
2576*6dbdd20aSAndroid Build Coastguard Worker   bool found_args = false;
2577*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
2578*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
2579*6dbdd20aSAndroid Build Coastguard Worker       continue;
2580*6dbdd20aSAndroid Build Coastguard Worker     const auto& track_event = packet.track_event();
2581*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.type() !=
2582*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN) {
2583*6dbdd20aSAndroid Build Coastguard Worker       continue;
2584*6dbdd20aSAndroid Build Coastguard Worker     }
2585*6dbdd20aSAndroid Build Coastguard Worker 
2586*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(track_event.flow_ids_old(), testing::ElementsAre(1u, 2u, 3u));
2587*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(track_event.flow_ids(), testing::ElementsAre(4u, 5u, 6u));
2588*6dbdd20aSAndroid Build Coastguard Worker     found_args = true;
2589*6dbdd20aSAndroid Build Coastguard Worker   }
2590*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_args);
2591*6dbdd20aSAndroid Build Coastguard Worker }
2592*6dbdd20aSAndroid Build Coastguard Worker 
2593*6dbdd20aSAndroid Build Coastguard Worker namespace {
2594*6dbdd20aSAndroid Build Coastguard Worker 
2595*6dbdd20aSAndroid Build Coastguard Worker struct LogMessage {
WriteIntoTrace__anonfc73210d0111::__anonfc73210d1511::LogMessage2596*6dbdd20aSAndroid Build Coastguard Worker   void WriteIntoTrace(
2597*6dbdd20aSAndroid Build Coastguard Worker       perfetto::TracedProto<perfetto::protos::pbzero::LogMessage> context)
2598*6dbdd20aSAndroid Build Coastguard Worker       const {
2599*6dbdd20aSAndroid Build Coastguard Worker     context->set_source_location_iid(1);
2600*6dbdd20aSAndroid Build Coastguard Worker     context->set_body_iid(2);
2601*6dbdd20aSAndroid Build Coastguard Worker   }
2602*6dbdd20aSAndroid Build Coastguard Worker };
2603*6dbdd20aSAndroid Build Coastguard Worker 
__anonfc73210d1602() 2604*6dbdd20aSAndroid Build Coastguard Worker auto GetWriteLogMessageRefLambda = []() {
2605*6dbdd20aSAndroid Build Coastguard Worker   return [](perfetto::EventContext& ctx) {
2606*6dbdd20aSAndroid Build Coastguard Worker     auto* log = ctx.event()->set_log_message();
2607*6dbdd20aSAndroid Build Coastguard Worker     log->set_source_location_iid(1);
2608*6dbdd20aSAndroid Build Coastguard Worker     log->set_body_iid(2);
2609*6dbdd20aSAndroid Build Coastguard Worker   };
2610*6dbdd20aSAndroid Build Coastguard Worker };
2611*6dbdd20aSAndroid Build Coastguard Worker 
CheckTypedArguments(const std::vector<char> & raw_trace,const char * event_name,perfetto::protos::gen::TrackEvent::Type type,std::function<void (const perfetto::protos::gen::TrackEvent &)> checker)2612*6dbdd20aSAndroid Build Coastguard Worker void CheckTypedArguments(
2613*6dbdd20aSAndroid Build Coastguard Worker     const std::vector<char>& raw_trace,
2614*6dbdd20aSAndroid Build Coastguard Worker     const char* event_name,
2615*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEvent::Type type,
2616*6dbdd20aSAndroid Build Coastguard Worker     std::function<void(const perfetto::protos::gen::TrackEvent&)> checker) {
2617*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace parsed_trace;
2618*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
2619*6dbdd20aSAndroid Build Coastguard Worker 
2620*6dbdd20aSAndroid Build Coastguard Worker   bool found_slice = false;
2621*6dbdd20aSAndroid Build Coastguard Worker   ParsedIncrementalState incremental_state;
2622*6dbdd20aSAndroid Build Coastguard Worker 
2623*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : parsed_trace.packet()) {
2624*6dbdd20aSAndroid Build Coastguard Worker     incremental_state.ClearIfNeeded(packet);
2625*6dbdd20aSAndroid Build Coastguard Worker     incremental_state.Parse(packet);
2626*6dbdd20aSAndroid Build Coastguard Worker 
2627*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
2628*6dbdd20aSAndroid Build Coastguard Worker       continue;
2629*6dbdd20aSAndroid Build Coastguard Worker     const auto& track_event = packet.track_event();
2630*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.type() != type) {
2631*6dbdd20aSAndroid Build Coastguard Worker       continue;
2632*6dbdd20aSAndroid Build Coastguard Worker     }
2633*6dbdd20aSAndroid Build Coastguard Worker     if (event_name &&
2634*6dbdd20aSAndroid Build Coastguard Worker         incremental_state.GetEventName(track_event) != event_name) {
2635*6dbdd20aSAndroid Build Coastguard Worker       continue;
2636*6dbdd20aSAndroid Build Coastguard Worker     }
2637*6dbdd20aSAndroid Build Coastguard Worker 
2638*6dbdd20aSAndroid Build Coastguard Worker     checker(track_event);
2639*6dbdd20aSAndroid Build Coastguard Worker     found_slice = true;
2640*6dbdd20aSAndroid Build Coastguard Worker   }
2641*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_slice);
2642*6dbdd20aSAndroid Build Coastguard Worker }
2643*6dbdd20aSAndroid Build Coastguard Worker 
CheckLogMessagePresent(const std::vector<char> & raw_trace)2644*6dbdd20aSAndroid Build Coastguard Worker void CheckLogMessagePresent(const std::vector<char>& raw_trace) {
2645*6dbdd20aSAndroid Build Coastguard Worker   CheckTypedArguments(raw_trace, nullptr,
2646*6dbdd20aSAndroid Build Coastguard Worker                       perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN,
2647*6dbdd20aSAndroid Build Coastguard Worker                       [](const perfetto::protos::gen::TrackEvent& track_event) {
2648*6dbdd20aSAndroid Build Coastguard Worker                         EXPECT_TRUE(track_event.has_log_message());
2649*6dbdd20aSAndroid Build Coastguard Worker                         const auto& log = track_event.log_message();
2650*6dbdd20aSAndroid Build Coastguard Worker                         EXPECT_EQ(1u, log.source_location_iid());
2651*6dbdd20aSAndroid Build Coastguard Worker                         EXPECT_EQ(2u, log.body_iid());
2652*6dbdd20aSAndroid Build Coastguard Worker                       });
2653*6dbdd20aSAndroid Build Coastguard Worker }
2654*6dbdd20aSAndroid Build Coastguard Worker 
2655*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
2656*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,InlineTrackEventTypedArgs_NestedSingle)2657*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, InlineTrackEventTypedArgs_NestedSingle) {
2658*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2659*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2660*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2661*6dbdd20aSAndroid Build Coastguard Worker 
2662*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "EventWithTypedArg",
2663*6dbdd20aSAndroid Build Coastguard Worker                     perfetto::protos::pbzero::TrackEvent::kLogMessage,
2664*6dbdd20aSAndroid Build Coastguard Worker                     LogMessage());
2665*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2666*6dbdd20aSAndroid Build Coastguard Worker 
2667*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2668*6dbdd20aSAndroid Build Coastguard Worker }
2669*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventThreadTime)2670*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventThreadTime) {
2671*6dbdd20aSAndroid Build Coastguard Worker   for (auto enable_thread_time : {true, false}) {
2672*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
2673*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.set_enable_thread_time_sampling(enable_thread_time);
2674*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"}, te_cfg);
2675*6dbdd20aSAndroid Build Coastguard Worker 
2676*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
2677*6dbdd20aSAndroid Build Coastguard Worker 
2678*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Track custom_track(1);
2679*6dbdd20aSAndroid Build Coastguard Worker 
2680*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "event1");
2681*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "event2");
2682*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "event3");
2683*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "event4", custom_track);
2684*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_END("foo");
2685*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_END("foo");
2686*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_END("foo");
2687*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_END("foo");
2688*6dbdd20aSAndroid Build Coastguard Worker 
2689*6dbdd20aSAndroid Build Coastguard Worker     auto trace = StopSessionAndReturnParsedTrace(tracing_session);
2690*6dbdd20aSAndroid Build Coastguard Worker 
2691*6dbdd20aSAndroid Build Coastguard Worker     bool found_counter_track_descriptor = false;
2692*6dbdd20aSAndroid Build Coastguard Worker     uint64_t thread_time_counter_uuid = 0;
2693*6dbdd20aSAndroid Build Coastguard Worker     uint64_t default_counter_uuid = 0;
2694*6dbdd20aSAndroid Build Coastguard Worker     std::unordered_set<std::string> event_names;
2695*6dbdd20aSAndroid Build Coastguard Worker     for (const auto& packet : trace.packet()) {
2696*6dbdd20aSAndroid Build Coastguard Worker       if (packet.has_track_descriptor() &&
2697*6dbdd20aSAndroid Build Coastguard Worker           packet.track_descriptor().has_counter()) {
2698*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_FALSE(found_counter_track_descriptor);
2699*6dbdd20aSAndroid Build Coastguard Worker         found_counter_track_descriptor = true;
2700*6dbdd20aSAndroid Build Coastguard Worker         thread_time_counter_uuid = packet.track_descriptor().uuid();
2701*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ("thread_time", packet.track_descriptor().static_name());
2702*6dbdd20aSAndroid Build Coastguard Worker         auto counter = packet.track_descriptor().counter();
2703*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(
2704*6dbdd20aSAndroid Build Coastguard Worker             perfetto::protos::gen::
2705*6dbdd20aSAndroid Build Coastguard Worker                 CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS,
2706*6dbdd20aSAndroid Build Coastguard Worker             counter.type());
2707*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(counter.is_incremental());
2708*6dbdd20aSAndroid Build Coastguard Worker       }
2709*6dbdd20aSAndroid Build Coastguard Worker       if (packet.has_trace_packet_defaults()) {
2710*6dbdd20aSAndroid Build Coastguard Worker         auto& defaults = packet.trace_packet_defaults().track_event_defaults();
2711*6dbdd20aSAndroid Build Coastguard Worker         ASSERT_EQ(enable_thread_time ? 1u : 0u,
2712*6dbdd20aSAndroid Build Coastguard Worker                   defaults.extra_counter_track_uuids().size());
2713*6dbdd20aSAndroid Build Coastguard Worker         if (enable_thread_time) {
2714*6dbdd20aSAndroid Build Coastguard Worker           default_counter_uuid = defaults.extra_counter_track_uuids().at(0);
2715*6dbdd20aSAndroid Build Coastguard Worker         }
2716*6dbdd20aSAndroid Build Coastguard Worker       }
2717*6dbdd20aSAndroid Build Coastguard Worker       if (packet.has_track_event()) {
2718*6dbdd20aSAndroid Build Coastguard Worker         std::string event_name;
2719*6dbdd20aSAndroid Build Coastguard Worker         if (packet.has_interned_data()) {
2720*6dbdd20aSAndroid Build Coastguard Worker           auto& event_names_info = packet.interned_data().event_names();
2721*6dbdd20aSAndroid Build Coastguard Worker           if (event_names_info.size() > 0) {
2722*6dbdd20aSAndroid Build Coastguard Worker             event_name = event_names_info[0].name();
2723*6dbdd20aSAndroid Build Coastguard Worker           }
2724*6dbdd20aSAndroid Build Coastguard Worker         }
2725*6dbdd20aSAndroid Build Coastguard Worker         event_names.insert(event_name);
2726*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ((enable_thread_time && event_name != "event4") ? 1u : 0u,
2727*6dbdd20aSAndroid Build Coastguard Worker                   packet.track_event().extra_counter_values().size());
2728*6dbdd20aSAndroid Build Coastguard Worker       }
2729*6dbdd20aSAndroid Build Coastguard Worker     }
2730*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(ContainsKey(event_names, "event1"));
2731*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(ContainsKey(event_names, "event2"));
2732*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(ContainsKey(event_names, "event3"));
2733*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(ContainsKey(event_names, "event4"));
2734*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(enable_thread_time, found_counter_track_descriptor);
2735*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(default_counter_uuid, thread_time_counter_uuid);
2736*6dbdd20aSAndroid Build Coastguard Worker     if (enable_thread_time) {
2737*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_GT(thread_time_counter_uuid, 0u);
2738*6dbdd20aSAndroid Build Coastguard Worker     } else {
2739*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(thread_time_counter_uuid, 0u);
2740*6dbdd20aSAndroid Build Coastguard Worker     }
2741*6dbdd20aSAndroid Build Coastguard Worker   }
2742*6dbdd20aSAndroid Build Coastguard Worker }
2743*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_TypedAndUntyped)2744*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_TypedAndUntyped) {
2745*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2746*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2747*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2748*6dbdd20aSAndroid Build Coastguard Worker 
2749*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "E",
2750*6dbdd20aSAndroid Build Coastguard Worker                     perfetto::protos::pbzero::TrackEvent::kLogMessage,
2751*6dbdd20aSAndroid Build Coastguard Worker                     LogMessage(), "arg", "value");
2752*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2753*6dbdd20aSAndroid Build Coastguard Worker 
2754*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2755*6dbdd20aSAndroid Build Coastguard Worker   std::string trace(raw_trace.data(), raw_trace.size());
2756*6dbdd20aSAndroid Build Coastguard Worker 
2757*6dbdd20aSAndroid Build Coastguard Worker   // Find typed argument.
2758*6dbdd20aSAndroid Build Coastguard Worker   CheckLogMessagePresent(raw_trace);
2759*6dbdd20aSAndroid Build Coastguard Worker 
2760*6dbdd20aSAndroid Build Coastguard Worker   // Find untyped argument.
2761*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2762*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2763*6dbdd20aSAndroid Build Coastguard Worker }
2764*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_UntypedAndTyped)2765*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_UntypedAndTyped) {
2766*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2767*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2768*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2769*6dbdd20aSAndroid Build Coastguard Worker 
2770*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "E", "arg", "value",
2771*6dbdd20aSAndroid Build Coastguard Worker                     perfetto::protos::pbzero::TrackEvent::kLogMessage,
2772*6dbdd20aSAndroid Build Coastguard Worker                     LogMessage());
2773*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2774*6dbdd20aSAndroid Build Coastguard Worker 
2775*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2776*6dbdd20aSAndroid Build Coastguard Worker 
2777*6dbdd20aSAndroid Build Coastguard Worker   // Find typed argument.
2778*6dbdd20aSAndroid Build Coastguard Worker   CheckLogMessagePresent(raw_trace);
2779*6dbdd20aSAndroid Build Coastguard Worker 
2780*6dbdd20aSAndroid Build Coastguard Worker   // Find untyped argument.
2781*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2782*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2783*6dbdd20aSAndroid Build Coastguard Worker }
2784*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_UntypedAndRefLambda)2785*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_UntypedAndRefLambda) {
2786*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2787*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2788*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2789*6dbdd20aSAndroid Build Coastguard Worker 
2790*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "E", "arg", "value", GetWriteLogMessageRefLambda());
2791*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2792*6dbdd20aSAndroid Build Coastguard Worker 
2793*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2794*6dbdd20aSAndroid Build Coastguard Worker 
2795*6dbdd20aSAndroid Build Coastguard Worker   // Find typed argument.
2796*6dbdd20aSAndroid Build Coastguard Worker   CheckLogMessagePresent(raw_trace);
2797*6dbdd20aSAndroid Build Coastguard Worker 
2798*6dbdd20aSAndroid Build Coastguard Worker   // Find untyped argument.
2799*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2800*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2801*6dbdd20aSAndroid Build Coastguard Worker }
2802*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_RefLambdaAndUntyped)2803*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndUntyped) {
2804*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2805*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2806*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2807*6dbdd20aSAndroid Build Coastguard Worker 
2808*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "E", GetWriteLogMessageRefLambda(), "arg", "value");
2809*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2810*6dbdd20aSAndroid Build Coastguard Worker 
2811*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2812*6dbdd20aSAndroid Build Coastguard Worker 
2813*6dbdd20aSAndroid Build Coastguard Worker   // Find typed argument.
2814*6dbdd20aSAndroid Build Coastguard Worker   CheckLogMessagePresent(raw_trace);
2815*6dbdd20aSAndroid Build Coastguard Worker 
2816*6dbdd20aSAndroid Build Coastguard Worker   // Find untyped argument.
2817*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2818*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2819*6dbdd20aSAndroid Build Coastguard Worker }
2820*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_RefLambdaAndTyped)2821*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndTyped) {
2822*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2823*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2824*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2825*6dbdd20aSAndroid Build Coastguard Worker 
2826*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN(
2827*6dbdd20aSAndroid Build Coastguard Worker       "foo", "E",
2828*6dbdd20aSAndroid Build Coastguard Worker       [](perfetto::EventContext& ctx) {
2829*6dbdd20aSAndroid Build Coastguard Worker         ctx.AddDebugAnnotation("arg", "value");
2830*6dbdd20aSAndroid Build Coastguard Worker       },
2831*6dbdd20aSAndroid Build Coastguard Worker       perfetto::protos::pbzero::TrackEvent::kLogMessage, LogMessage());
2832*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2833*6dbdd20aSAndroid Build Coastguard Worker 
2834*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2835*6dbdd20aSAndroid Build Coastguard Worker 
2836*6dbdd20aSAndroid Build Coastguard Worker   // Find typed argument.
2837*6dbdd20aSAndroid Build Coastguard Worker   CheckLogMessagePresent(raw_trace);
2838*6dbdd20aSAndroid Build Coastguard Worker 
2839*6dbdd20aSAndroid Build Coastguard Worker   // Find untyped argument.
2840*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2841*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2842*6dbdd20aSAndroid Build Coastguard Worker }
2843*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_TypedAndRefLambda)2844*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_TypedAndRefLambda) {
2845*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2846*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2847*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2848*6dbdd20aSAndroid Build Coastguard Worker 
2849*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "E",
2850*6dbdd20aSAndroid Build Coastguard Worker                     perfetto::protos::pbzero::TrackEvent::kLogMessage,
2851*6dbdd20aSAndroid Build Coastguard Worker                     LogMessage(), [](perfetto::EventContext& ctx) {
2852*6dbdd20aSAndroid Build Coastguard Worker                       ctx.AddDebugAnnotation("arg", "value");
2853*6dbdd20aSAndroid Build Coastguard Worker                     });
2854*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2855*6dbdd20aSAndroid Build Coastguard Worker 
2856*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2857*6dbdd20aSAndroid Build Coastguard Worker 
2858*6dbdd20aSAndroid Build Coastguard Worker   // Find typed argument.
2859*6dbdd20aSAndroid Build Coastguard Worker   CheckLogMessagePresent(raw_trace);
2860*6dbdd20aSAndroid Build Coastguard Worker 
2861*6dbdd20aSAndroid Build Coastguard Worker   // Find untyped argument.
2862*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2863*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2864*6dbdd20aSAndroid Build Coastguard Worker }
2865*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_RefLambdaAndRefLambda)2866*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndRefLambda) {
2867*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2868*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2869*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2870*6dbdd20aSAndroid Build Coastguard Worker 
2871*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN(
2872*6dbdd20aSAndroid Build Coastguard Worker       "foo", "E",
2873*6dbdd20aSAndroid Build Coastguard Worker       [](perfetto::EventContext& ctx) {
2874*6dbdd20aSAndroid Build Coastguard Worker         ctx.AddDebugAnnotation("arg1", "value1");
2875*6dbdd20aSAndroid Build Coastguard Worker       },
2876*6dbdd20aSAndroid Build Coastguard Worker       [](perfetto::EventContext& ctx) {
2877*6dbdd20aSAndroid Build Coastguard Worker         ctx.AddDebugAnnotation("arg2", "value2");
2878*6dbdd20aSAndroid Build Coastguard Worker       });
2879*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2880*6dbdd20aSAndroid Build Coastguard Worker 
2881*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2882*6dbdd20aSAndroid Build Coastguard Worker 
2883*6dbdd20aSAndroid Build Coastguard Worker   // Find untyped arguments.
2884*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
2885*6dbdd20aSAndroid Build Coastguard Worker       ReadSlicesFromTrace(raw_trace),
2886*6dbdd20aSAndroid Build Coastguard Worker       ElementsAre("B:foo.E(arg1=(string)value1,arg2=(string)value2)", "E"));
2887*6dbdd20aSAndroid Build Coastguard Worker }
2888*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_RefLambdaAndLambda)2889*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_RefLambdaAndLambda) {
2890*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2891*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2892*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2893*6dbdd20aSAndroid Build Coastguard Worker 
2894*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN(
2895*6dbdd20aSAndroid Build Coastguard Worker       "foo", "E",
2896*6dbdd20aSAndroid Build Coastguard Worker       [](perfetto::EventContext& ctx) {
2897*6dbdd20aSAndroid Build Coastguard Worker         ctx.AddDebugAnnotation("arg1", "value1");
2898*6dbdd20aSAndroid Build Coastguard Worker       },
2899*6dbdd20aSAndroid Build Coastguard Worker       [](perfetto::EventContext ctx) {
2900*6dbdd20aSAndroid Build Coastguard Worker         ctx.AddDebugAnnotation("arg2", "value2");
2901*6dbdd20aSAndroid Build Coastguard Worker       });
2902*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2903*6dbdd20aSAndroid Build Coastguard Worker 
2904*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2905*6dbdd20aSAndroid Build Coastguard Worker 
2906*6dbdd20aSAndroid Build Coastguard Worker   // Find untyped arguments.
2907*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
2908*6dbdd20aSAndroid Build Coastguard Worker       ReadSlicesFromTrace(raw_trace),
2909*6dbdd20aSAndroid Build Coastguard Worker       ElementsAre("B:foo.E(arg1=(string)value1,arg2=(string)value2)", "E"));
2910*6dbdd20aSAndroid Build Coastguard Worker }
2911*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_RefLambda)2912*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_RefLambda) {
2913*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2914*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2915*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2916*6dbdd20aSAndroid Build Coastguard Worker 
2917*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "E", [](perfetto::EventContext& ctx) {
2918*6dbdd20aSAndroid Build Coastguard Worker     ctx.AddDebugAnnotation("arg", "value");
2919*6dbdd20aSAndroid Build Coastguard Worker   });
2920*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
2921*6dbdd20aSAndroid Build Coastguard Worker 
2922*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2923*6dbdd20aSAndroid Build Coastguard Worker 
2924*6dbdd20aSAndroid Build Coastguard Worker   // Find untyped argument.
2925*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2926*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:foo.E(arg=(string)value)", "E"));
2927*6dbdd20aSAndroid Build Coastguard Worker }
2928*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_Flow_Global)2929*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_Flow_Global) {
2930*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2931*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2932*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2933*6dbdd20aSAndroid Build Coastguard Worker 
2934*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "E1", perfetto::Flow::Global(42));
2935*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "E2", perfetto::TerminatingFlow::Global(42));
2936*6dbdd20aSAndroid Build Coastguard Worker 
2937*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2938*6dbdd20aSAndroid Build Coastguard Worker 
2939*6dbdd20aSAndroid Build Coastguard Worker   // Find typed argument.
2940*6dbdd20aSAndroid Build Coastguard Worker   CheckTypedArguments(
2941*6dbdd20aSAndroid Build Coastguard Worker       raw_trace, "E1", perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
2942*6dbdd20aSAndroid Build Coastguard Worker       [](const perfetto::protos::gen::TrackEvent& track_event) {
2943*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(track_event.flow_ids_old().empty());
2944*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_THAT(track_event.flow_ids(), testing::ElementsAre(42u));
2945*6dbdd20aSAndroid Build Coastguard Worker       });
2946*6dbdd20aSAndroid Build Coastguard Worker }
2947*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_Lambda_Multisession)2948*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_Lambda_Multisession) {
2949*6dbdd20aSAndroid Build Coastguard Worker   // Create two simultaneous tracing sessions.
2950*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2951*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session2 = NewTraceWithCategories({"foo"});
2952*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2953*6dbdd20aSAndroid Build Coastguard Worker   tracing_session2->get()->StartBlocking();
2954*6dbdd20aSAndroid Build Coastguard Worker 
2955*6dbdd20aSAndroid Build Coastguard Worker   // Emit an event in both sessions using an argument function.
2956*6dbdd20aSAndroid Build Coastguard Worker   auto make_arg = []() -> std::function<void(perfetto::EventContext&)> {
2957*6dbdd20aSAndroid Build Coastguard Worker     return [](perfetto::EventContext& ctx) {
2958*6dbdd20aSAndroid Build Coastguard Worker       ctx.event()->set_type(perfetto::protos::pbzero::TrackEvent::TYPE_INSTANT);
2959*6dbdd20aSAndroid Build Coastguard Worker       ctx.event()->add_flow_ids(42);
2960*6dbdd20aSAndroid Build Coastguard Worker     };
2961*6dbdd20aSAndroid Build Coastguard Worker   };
2962*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "E1", make_arg());
2963*6dbdd20aSAndroid Build Coastguard Worker 
2964*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2965*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace2 = StopSessionAndReturnBytes(tracing_session2);
2966*6dbdd20aSAndroid Build Coastguard Worker 
2967*6dbdd20aSAndroid Build Coastguard Worker   // Check that the event was output twice.
2968*6dbdd20aSAndroid Build Coastguard Worker   CheckTypedArguments(
2969*6dbdd20aSAndroid Build Coastguard Worker       raw_trace, "E1", perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
2970*6dbdd20aSAndroid Build Coastguard Worker       [](const perfetto::protos::gen::TrackEvent& track_event) {
2971*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(track_event.flow_ids_old().empty());
2972*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_THAT(track_event.flow_ids(), testing::ElementsAre(42u));
2973*6dbdd20aSAndroid Build Coastguard Worker       });
2974*6dbdd20aSAndroid Build Coastguard Worker   CheckTypedArguments(
2975*6dbdd20aSAndroid Build Coastguard Worker       raw_trace2, "E1", perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
2976*6dbdd20aSAndroid Build Coastguard Worker       [](const perfetto::protos::gen::TrackEvent& track_event) {
2977*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(track_event.flow_ids_old().empty());
2978*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_THAT(track_event.flow_ids(), testing::ElementsAre(42u));
2979*6dbdd20aSAndroid Build Coastguard Worker       });
2980*6dbdd20aSAndroid Build Coastguard Worker }
2981*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_MultipleFlows)2982*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_MultipleFlows) {
2983*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
2984*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
2985*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
2986*6dbdd20aSAndroid Build Coastguard Worker 
2987*6dbdd20aSAndroid Build Coastguard Worker   {
2988*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT("foo", "E1", perfetto::Flow::Global(1),
2989*6dbdd20aSAndroid Build Coastguard Worker                 perfetto::Flow::Global(2), perfetto::Flow::Global(3));
2990*6dbdd20aSAndroid Build Coastguard Worker   }
2991*6dbdd20aSAndroid Build Coastguard Worker   {
2992*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT("foo", "E2", perfetto::Flow::Global(1),
2993*6dbdd20aSAndroid Build Coastguard Worker                 perfetto::TerminatingFlow::Global(2));
2994*6dbdd20aSAndroid Build Coastguard Worker   }
2995*6dbdd20aSAndroid Build Coastguard Worker   { TRACE_EVENT("foo", "E3", perfetto::TerminatingFlow::Global(3)); }
2996*6dbdd20aSAndroid Build Coastguard Worker 
2997*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
2998*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
2999*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:foo.E1(flow_ids=1,2,3)", "E",
3000*6dbdd20aSAndroid Build Coastguard Worker                           "B:foo.E2(flow_ids=1)(terminating_flow_ids=2)", "E",
3001*6dbdd20aSAndroid Build Coastguard Worker                           "B:foo.E3(terminating_flow_ids=3)", "E"));
3002*6dbdd20aSAndroid Build Coastguard Worker }
3003*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_Flow_ProcessScoped)3004*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_Flow_ProcessScoped) {
3005*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3006*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
3007*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3008*6dbdd20aSAndroid Build Coastguard Worker 
3009*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "E1", perfetto::Flow::ProcessScoped(1));
3010*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "E2", perfetto::TerminatingFlow::ProcessScoped(1));
3011*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "Flush");
3012*6dbdd20aSAndroid Build Coastguard Worker 
3013*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
3014*6dbdd20aSAndroid Build Coastguard Worker 
3015*6dbdd20aSAndroid Build Coastguard Worker   // Find typed arguments.
3016*6dbdd20aSAndroid Build Coastguard Worker   CheckTypedArguments(raw_trace, "E1",
3017*6dbdd20aSAndroid Build Coastguard Worker                       perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
3018*6dbdd20aSAndroid Build Coastguard Worker                       [](const perfetto::protos::gen::TrackEvent& track_event) {
3019*6dbdd20aSAndroid Build Coastguard Worker                         EXPECT_EQ(track_event.flow_ids_old_size(), 0);
3020*6dbdd20aSAndroid Build Coastguard Worker                         EXPECT_EQ(track_event.flow_ids_size(), 1);
3021*6dbdd20aSAndroid Build Coastguard Worker                       });
3022*6dbdd20aSAndroid Build Coastguard Worker   CheckTypedArguments(
3023*6dbdd20aSAndroid Build Coastguard Worker       raw_trace, "E2", perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
3024*6dbdd20aSAndroid Build Coastguard Worker       [](const perfetto::protos::gen::TrackEvent& track_event) {
3025*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(track_event.terminating_flow_ids_old_size(), 0);
3026*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(track_event.terminating_flow_ids_size(), 1);
3027*6dbdd20aSAndroid Build Coastguard Worker       });
3028*6dbdd20aSAndroid Build Coastguard Worker }
3029*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgs_Flow_FromPointer)3030*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgs_Flow_FromPointer) {
3031*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3032*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
3033*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3034*6dbdd20aSAndroid Build Coastguard Worker 
3035*6dbdd20aSAndroid Build Coastguard Worker   int a;
3036*6dbdd20aSAndroid Build Coastguard Worker   int* ptr = &a;
3037*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "E1", perfetto::Flow::FromPointer(ptr));
3038*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "E2", perfetto::TerminatingFlow::FromPointer(ptr));
3039*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "Flush");
3040*6dbdd20aSAndroid Build Coastguard Worker 
3041*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
3042*6dbdd20aSAndroid Build Coastguard Worker 
3043*6dbdd20aSAndroid Build Coastguard Worker   // Find typed arguments.
3044*6dbdd20aSAndroid Build Coastguard Worker   CheckTypedArguments(raw_trace, "E1",
3045*6dbdd20aSAndroid Build Coastguard Worker                       perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
3046*6dbdd20aSAndroid Build Coastguard Worker                       [](const perfetto::protos::gen::TrackEvent& track_event) {
3047*6dbdd20aSAndroid Build Coastguard Worker                         EXPECT_EQ(track_event.flow_ids_old_size(), 0);
3048*6dbdd20aSAndroid Build Coastguard Worker                         EXPECT_EQ(track_event.flow_ids_size(), 1);
3049*6dbdd20aSAndroid Build Coastguard Worker                       });
3050*6dbdd20aSAndroid Build Coastguard Worker   CheckTypedArguments(
3051*6dbdd20aSAndroid Build Coastguard Worker       raw_trace, "E2", perfetto::protos::gen::TrackEvent::TYPE_INSTANT,
3052*6dbdd20aSAndroid Build Coastguard Worker       [](const perfetto::protos::gen::TrackEvent& track_event) {
3053*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(track_event.terminating_flow_ids_old_size(), 0);
3054*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(track_event.terminating_flow_ids_size(), 1);
3055*6dbdd20aSAndroid Build Coastguard Worker       });
3056*6dbdd20aSAndroid Build Coastguard Worker }
3057*6dbdd20aSAndroid Build Coastguard Worker 
3058*6dbdd20aSAndroid Build Coastguard Worker struct InternedLogMessageBody
3059*6dbdd20aSAndroid Build Coastguard Worker     : public perfetto::TrackEventInternedDataIndex<
3060*6dbdd20aSAndroid Build Coastguard Worker           InternedLogMessageBody,
3061*6dbdd20aSAndroid Build Coastguard Worker           perfetto::protos::pbzero::InternedData::kLogMessageBodyFieldNumber,
3062*6dbdd20aSAndroid Build Coastguard Worker           std::string> {
Add__anonfc73210d0111::InternedLogMessageBody3063*6dbdd20aSAndroid Build Coastguard Worker   static void Add(perfetto::protos::pbzero::InternedData* interned_data,
3064*6dbdd20aSAndroid Build Coastguard Worker                   size_t iid,
3065*6dbdd20aSAndroid Build Coastguard Worker                   const std::string& value) {
3066*6dbdd20aSAndroid Build Coastguard Worker     auto l = interned_data->add_log_message_body();
3067*6dbdd20aSAndroid Build Coastguard Worker     l->set_iid(iid);
3068*6dbdd20aSAndroid Build Coastguard Worker     l->set_body(value.data(), value.size());
3069*6dbdd20aSAndroid Build Coastguard Worker     commit_count++;
3070*6dbdd20aSAndroid Build Coastguard Worker   }
3071*6dbdd20aSAndroid Build Coastguard Worker 
3072*6dbdd20aSAndroid Build Coastguard Worker   static int commit_count;
3073*6dbdd20aSAndroid Build Coastguard Worker };
3074*6dbdd20aSAndroid Build Coastguard Worker 
3075*6dbdd20aSAndroid Build Coastguard Worker int InternedLogMessageBody::commit_count = 0;
3076*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventTypedArgsWithInterning)3077*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventTypedArgsWithInterning) {
3078*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3079*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
3080*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3081*6dbdd20aSAndroid Build Coastguard Worker 
3082*6dbdd20aSAndroid Build Coastguard Worker   std::stringstream large_message;
3083*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < 512; i++)
3084*6dbdd20aSAndroid Build Coastguard Worker     large_message << i << ". Something wicked this way comes. ";
3085*6dbdd20aSAndroid Build Coastguard Worker 
3086*6dbdd20aSAndroid Build Coastguard Worker   size_t body_iid;
3087*6dbdd20aSAndroid Build Coastguard Worker   InternedLogMessageBody::commit_count = 0;
3088*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
3089*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(0, InternedLogMessageBody::commit_count);
3090*6dbdd20aSAndroid Build Coastguard Worker     body_iid = InternedLogMessageBody::Get(&ctx, "Alas, poor Yorick!");
3091*6dbdd20aSAndroid Build Coastguard Worker     auto log = ctx.event()->set_log_message();
3092*6dbdd20aSAndroid Build Coastguard Worker     log->set_body_iid(body_iid);
3093*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(1, InternedLogMessageBody::commit_count);
3094*6dbdd20aSAndroid Build Coastguard Worker 
3095*6dbdd20aSAndroid Build Coastguard Worker     auto body_iid2 = InternedLogMessageBody::Get(&ctx, "Alas, poor Yorick!");
3096*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(body_iid, body_iid2);
3097*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(1, InternedLogMessageBody::commit_count);
3098*6dbdd20aSAndroid Build Coastguard Worker   });
3099*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
3100*6dbdd20aSAndroid Build Coastguard Worker 
3101*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
3102*6dbdd20aSAndroid Build Coastguard Worker     // Check that very large amounts of interned data works.
3103*6dbdd20aSAndroid Build Coastguard Worker     auto log = ctx.event()->set_log_message();
3104*6dbdd20aSAndroid Build Coastguard Worker     log->set_body_iid(InternedLogMessageBody::Get(&ctx, large_message.str()));
3105*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(2, InternedLogMessageBody::commit_count);
3106*6dbdd20aSAndroid Build Coastguard Worker   });
3107*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
3108*6dbdd20aSAndroid Build Coastguard Worker 
3109*6dbdd20aSAndroid Build Coastguard Worker   // Make sure interned data persists across trace points.
3110*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
3111*6dbdd20aSAndroid Build Coastguard Worker     auto body_iid2 = InternedLogMessageBody::Get(&ctx, "Alas, poor Yorick!");
3112*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(body_iid, body_iid2);
3113*6dbdd20aSAndroid Build Coastguard Worker 
3114*6dbdd20aSAndroid Build Coastguard Worker     auto body_iid3 = InternedLogMessageBody::Get(&ctx, "I knew him, Horatio");
3115*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_NE(body_iid, body_iid3);
3116*6dbdd20aSAndroid Build Coastguard Worker     auto log = ctx.event()->set_log_message();
3117*6dbdd20aSAndroid Build Coastguard Worker     log->set_body_iid(body_iid3);
3118*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(3, InternedLogMessageBody::commit_count);
3119*6dbdd20aSAndroid Build Coastguard Worker   });
3120*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
3121*6dbdd20aSAndroid Build Coastguard Worker 
3122*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
3123*6dbdd20aSAndroid Build Coastguard Worker   auto log_messages = ReadLogMessagesFromTrace(tracing_session->get());
3124*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(log_messages,
3125*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("Alas, poor Yorick!", large_message.str(),
3126*6dbdd20aSAndroid Build Coastguard Worker                           "I knew him, Horatio"));
3127*6dbdd20aSAndroid Build Coastguard Worker }
3128*6dbdd20aSAndroid Build Coastguard Worker 
3129*6dbdd20aSAndroid Build Coastguard Worker struct InternedLogMessageBodySmall
3130*6dbdd20aSAndroid Build Coastguard Worker     : public perfetto::TrackEventInternedDataIndex<
3131*6dbdd20aSAndroid Build Coastguard Worker           InternedLogMessageBodySmall,
3132*6dbdd20aSAndroid Build Coastguard Worker           perfetto::protos::pbzero::InternedData::kLogMessageBodyFieldNumber,
3133*6dbdd20aSAndroid Build Coastguard Worker           const char*,
3134*6dbdd20aSAndroid Build Coastguard Worker           perfetto::SmallInternedDataTraits> {
Add__anonfc73210d0111::InternedLogMessageBodySmall3135*6dbdd20aSAndroid Build Coastguard Worker   static void Add(perfetto::protos::pbzero::InternedData* interned_data,
3136*6dbdd20aSAndroid Build Coastguard Worker                   size_t iid,
3137*6dbdd20aSAndroid Build Coastguard Worker                   const char* value) {
3138*6dbdd20aSAndroid Build Coastguard Worker     auto l = interned_data->add_log_message_body();
3139*6dbdd20aSAndroid Build Coastguard Worker     l->set_iid(iid);
3140*6dbdd20aSAndroid Build Coastguard Worker     l->set_body(value);
3141*6dbdd20aSAndroid Build Coastguard Worker   }
3142*6dbdd20aSAndroid Build Coastguard Worker };
3143*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventTypedArgsWithInterningByValue)3144*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventTypedArgsWithInterningByValue) {
3145*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3146*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
3147*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3148*6dbdd20aSAndroid Build Coastguard Worker 
3149*6dbdd20aSAndroid Build Coastguard Worker   size_t body_iid;
3150*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
3151*6dbdd20aSAndroid Build Coastguard Worker     body_iid = InternedLogMessageBodySmall::Get(&ctx, "This above all:");
3152*6dbdd20aSAndroid Build Coastguard Worker     auto log = ctx.event()->set_log_message();
3153*6dbdd20aSAndroid Build Coastguard Worker     log->set_body_iid(body_iid);
3154*6dbdd20aSAndroid Build Coastguard Worker 
3155*6dbdd20aSAndroid Build Coastguard Worker     auto body_iid2 = InternedLogMessageBodySmall::Get(&ctx, "This above all:");
3156*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(body_iid, body_iid2);
3157*6dbdd20aSAndroid Build Coastguard Worker 
3158*6dbdd20aSAndroid Build Coastguard Worker     auto body_iid3 =
3159*6dbdd20aSAndroid Build Coastguard Worker         InternedLogMessageBodySmall::Get(&ctx, "to thine own self be true");
3160*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_NE(body_iid, body_iid3);
3161*6dbdd20aSAndroid Build Coastguard Worker   });
3162*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
3163*6dbdd20aSAndroid Build Coastguard Worker 
3164*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
3165*6dbdd20aSAndroid Build Coastguard Worker   auto log_messages = ReadLogMessagesFromTrace(tracing_session->get());
3166*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(log_messages, ElementsAre("This above all:"));
3167*6dbdd20aSAndroid Build Coastguard Worker }
3168*6dbdd20aSAndroid Build Coastguard Worker 
3169*6dbdd20aSAndroid Build Coastguard Worker struct InternedLogMessageBodyHashed
3170*6dbdd20aSAndroid Build Coastguard Worker     : public perfetto::TrackEventInternedDataIndex<
3171*6dbdd20aSAndroid Build Coastguard Worker           InternedLogMessageBodyHashed,
3172*6dbdd20aSAndroid Build Coastguard Worker           perfetto::protos::pbzero::InternedData::kLogMessageBodyFieldNumber,
3173*6dbdd20aSAndroid Build Coastguard Worker           std::string,
3174*6dbdd20aSAndroid Build Coastguard Worker           perfetto::HashedInternedDataTraits> {
Add__anonfc73210d0111::InternedLogMessageBodyHashed3175*6dbdd20aSAndroid Build Coastguard Worker   static void Add(perfetto::protos::pbzero::InternedData* interned_data,
3176*6dbdd20aSAndroid Build Coastguard Worker                   size_t iid,
3177*6dbdd20aSAndroid Build Coastguard Worker                   const std::string& value) {
3178*6dbdd20aSAndroid Build Coastguard Worker     auto l = interned_data->add_log_message_body();
3179*6dbdd20aSAndroid Build Coastguard Worker     l->set_iid(iid);
3180*6dbdd20aSAndroid Build Coastguard Worker     l->set_body(value.data(), value.size());
3181*6dbdd20aSAndroid Build Coastguard Worker   }
3182*6dbdd20aSAndroid Build Coastguard Worker };
3183*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventTypedArgsWithInterningByHashing)3184*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventTypedArgsWithInterningByHashing) {
3185*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3186*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
3187*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3188*6dbdd20aSAndroid Build Coastguard Worker 
3189*6dbdd20aSAndroid Build Coastguard Worker   size_t body_iid;
3190*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
3191*6dbdd20aSAndroid Build Coastguard Worker     // Test using a dynamically created interned value.
3192*6dbdd20aSAndroid Build Coastguard Worker     body_iid = InternedLogMessageBodyHashed::Get(
3193*6dbdd20aSAndroid Build Coastguard Worker         &ctx, std::string("Though this ") + "be madness,");
3194*6dbdd20aSAndroid Build Coastguard Worker     auto log = ctx.event()->set_log_message();
3195*6dbdd20aSAndroid Build Coastguard Worker     log->set_body_iid(body_iid);
3196*6dbdd20aSAndroid Build Coastguard Worker 
3197*6dbdd20aSAndroid Build Coastguard Worker     auto body_iid2 =
3198*6dbdd20aSAndroid Build Coastguard Worker         InternedLogMessageBodyHashed::Get(&ctx, "Though this be madness,");
3199*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(body_iid, body_iid2);
3200*6dbdd20aSAndroid Build Coastguard Worker 
3201*6dbdd20aSAndroid Build Coastguard Worker     auto body_iid3 =
3202*6dbdd20aSAndroid Build Coastguard Worker         InternedLogMessageBodyHashed::Get(&ctx, "yet there is method in’t");
3203*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_NE(body_iid, body_iid3);
3204*6dbdd20aSAndroid Build Coastguard Worker   });
3205*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
3206*6dbdd20aSAndroid Build Coastguard Worker 
3207*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
3208*6dbdd20aSAndroid Build Coastguard Worker   auto log_messages = ReadLogMessagesFromTrace(tracing_session->get());
3209*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(log_messages, ElementsAre("Though this be madness,"));
3210*6dbdd20aSAndroid Build Coastguard Worker }
3211*6dbdd20aSAndroid Build Coastguard Worker 
3212*6dbdd20aSAndroid Build Coastguard Worker struct InternedSourceLocation
3213*6dbdd20aSAndroid Build Coastguard Worker     : public perfetto::TrackEventInternedDataIndex<
3214*6dbdd20aSAndroid Build Coastguard Worker           InternedSourceLocation,
3215*6dbdd20aSAndroid Build Coastguard Worker           perfetto::protos::pbzero::InternedData::kSourceLocationsFieldNumber,
3216*6dbdd20aSAndroid Build Coastguard Worker           SourceLocation> {
Add__anonfc73210d0111::InternedSourceLocation3217*6dbdd20aSAndroid Build Coastguard Worker   static void Add(perfetto::protos::pbzero::InternedData* interned_data,
3218*6dbdd20aSAndroid Build Coastguard Worker                   size_t iid,
3219*6dbdd20aSAndroid Build Coastguard Worker                   const SourceLocation& value) {
3220*6dbdd20aSAndroid Build Coastguard Worker     auto l = interned_data->add_source_locations();
3221*6dbdd20aSAndroid Build Coastguard Worker     auto file_name = std::get<0>(value);
3222*6dbdd20aSAndroid Build Coastguard Worker     auto function_name = std::get<1>(value);
3223*6dbdd20aSAndroid Build Coastguard Worker     auto line_number = std::get<2>(value);
3224*6dbdd20aSAndroid Build Coastguard Worker     l->set_iid(iid);
3225*6dbdd20aSAndroid Build Coastguard Worker     l->set_file_name(file_name);
3226*6dbdd20aSAndroid Build Coastguard Worker     l->set_function_name(function_name);
3227*6dbdd20aSAndroid Build Coastguard Worker     l->set_line_number(line_number);
3228*6dbdd20aSAndroid Build Coastguard Worker   }
3229*6dbdd20aSAndroid Build Coastguard Worker };
3230*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventTypedArgsWithInterningComplexValue)3231*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventTypedArgsWithInterningComplexValue) {
3232*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3233*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
3234*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3235*6dbdd20aSAndroid Build Coastguard Worker 
3236*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "EventWithState", [&](perfetto::EventContext ctx) {
3237*6dbdd20aSAndroid Build Coastguard Worker     const SourceLocation location{"file.cc", "SomeFunction", 123};
3238*6dbdd20aSAndroid Build Coastguard Worker     auto location_iid = InternedSourceLocation::Get(&ctx, location);
3239*6dbdd20aSAndroid Build Coastguard Worker     auto body_iid = InternedLogMessageBody::Get(&ctx, "To be, or not to be");
3240*6dbdd20aSAndroid Build Coastguard Worker     auto log = ctx.event()->set_log_message();
3241*6dbdd20aSAndroid Build Coastguard Worker     log->set_source_location_iid(location_iid);
3242*6dbdd20aSAndroid Build Coastguard Worker     log->set_body_iid(body_iid);
3243*6dbdd20aSAndroid Build Coastguard Worker 
3244*6dbdd20aSAndroid Build Coastguard Worker     auto location_iid2 = InternedSourceLocation::Get(&ctx, location);
3245*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(location_iid, location_iid2);
3246*6dbdd20aSAndroid Build Coastguard Worker 
3247*6dbdd20aSAndroid Build Coastguard Worker     const SourceLocation location2{"file.cc", "SomeFunction", 456};
3248*6dbdd20aSAndroid Build Coastguard Worker     auto location_iid3 = InternedSourceLocation::Get(&ctx, location2);
3249*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_NE(location_iid, location_iid3);
3250*6dbdd20aSAndroid Build Coastguard Worker   });
3251*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
3252*6dbdd20aSAndroid Build Coastguard Worker 
3253*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
3254*6dbdd20aSAndroid Build Coastguard Worker   auto log_messages = ReadLogMessagesFromTrace(tracing_session->get());
3255*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(log_messages,
3256*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("SomeFunction(file.cc:123): To be, or not to be"));
3257*6dbdd20aSAndroid Build Coastguard Worker }
3258*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventScoped)3259*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventScoped) {
3260*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3261*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3262*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3263*6dbdd20aSAndroid Build Coastguard Worker 
3264*6dbdd20aSAndroid Build Coastguard Worker   {
3265*6dbdd20aSAndroid Build Coastguard Worker     uint64_t arg = 123;
3266*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT("test", "TestEventWithArgs", [&](perfetto::EventContext ctx) {
3267*6dbdd20aSAndroid Build Coastguard Worker       ctx.event()->set_log_message()->set_body_iid(arg);
3268*6dbdd20aSAndroid Build Coastguard Worker     });
3269*6dbdd20aSAndroid Build Coastguard Worker   }
3270*6dbdd20aSAndroid Build Coastguard Worker 
3271*6dbdd20aSAndroid Build Coastguard Worker   // Ensure a single line if statement counts as a valid scope for the macro.
3272*6dbdd20aSAndroid Build Coastguard Worker   if (true)
3273*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT("test", "SingleLineTestEvent");
3274*6dbdd20aSAndroid Build Coastguard Worker 
3275*6dbdd20aSAndroid Build Coastguard Worker   {
3276*6dbdd20aSAndroid Build Coastguard Worker     // Make sure you can have multiple scoped events in the same scope.
3277*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT("test", "TestEvent");
3278*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT("test", "AnotherEvent");
3279*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT("foo", "DisabledEvent");
3280*6dbdd20aSAndroid Build Coastguard Worker   }
3281*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3282*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
3283*6dbdd20aSAndroid Build Coastguard Worker       slices,
3284*6dbdd20aSAndroid Build Coastguard Worker       ElementsAre("B:test.TestEventWithArgs", "E", "B:test.SingleLineTestEvent",
3285*6dbdd20aSAndroid Build Coastguard Worker                   "E", "B:test.TestEvent", "B:test.AnotherEvent", "E", "E"));
3286*6dbdd20aSAndroid Build Coastguard Worker }
3287*6dbdd20aSAndroid Build Coastguard Worker 
3288*6dbdd20aSAndroid Build Coastguard Worker // A class similar to what Protozero generates for extended message.
3289*6dbdd20aSAndroid Build Coastguard Worker class TestTrackEvent : public perfetto::protos::pbzero::TrackEvent {
3290*6dbdd20aSAndroid Build Coastguard Worker  public:
3291*6dbdd20aSAndroid Build Coastguard Worker   static const int field_number = 9901;
3292*6dbdd20aSAndroid Build Coastguard Worker 
set_extension_value(int value)3293*6dbdd20aSAndroid Build Coastguard Worker   void set_extension_value(int value) {
3294*6dbdd20aSAndroid Build Coastguard Worker     // 9900-10000 is the range of extension field numbers reserved for testing.
3295*6dbdd20aSAndroid Build Coastguard Worker     AppendTinyVarInt(field_number, value);
3296*6dbdd20aSAndroid Build Coastguard Worker   }
3297*6dbdd20aSAndroid Build Coastguard Worker };
3298*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ExtensionClass)3299*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ExtensionClass) {
3300*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3301*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3302*6dbdd20aSAndroid Build Coastguard Worker 
3303*6dbdd20aSAndroid Build Coastguard Worker   {
3304*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT("test", "TestEventWithExtensionArgs",
3305*6dbdd20aSAndroid Build Coastguard Worker                 [&](perfetto::EventContext ctx) {
3306*6dbdd20aSAndroid Build Coastguard Worker                   ctx.event<perfetto::protos::pbzero::TestExtension>()
3307*6dbdd20aSAndroid Build Coastguard Worker                       ->add_int_extension_for_testing(42);
3308*6dbdd20aSAndroid Build Coastguard Worker                 });
3309*6dbdd20aSAndroid Build Coastguard Worker   }
3310*6dbdd20aSAndroid Build Coastguard Worker 
3311*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
3312*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_GE(raw_trace.size(), 0u);
3313*6dbdd20aSAndroid Build Coastguard Worker 
3314*6dbdd20aSAndroid Build Coastguard Worker   bool found_extension = false;
3315*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::pbzero::Trace_Decoder trace(
3316*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<uint8_t*>(raw_trace.data()), raw_trace.size());
3317*6dbdd20aSAndroid Build Coastguard Worker 
3318*6dbdd20aSAndroid Build Coastguard Worker   for (auto it = trace.packet(); it; ++it) {
3319*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::pbzero::TracePacket_Decoder packet(it->data(),
3320*6dbdd20aSAndroid Build Coastguard Worker                                                          it->size());
3321*6dbdd20aSAndroid Build Coastguard Worker 
3322*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
3323*6dbdd20aSAndroid Build Coastguard Worker       continue;
3324*6dbdd20aSAndroid Build Coastguard Worker 
3325*6dbdd20aSAndroid Build Coastguard Worker     auto track_event = packet.track_event();
3326*6dbdd20aSAndroid Build Coastguard Worker     protozero::ProtoDecoder decoder(track_event.data, track_event.size);
3327*6dbdd20aSAndroid Build Coastguard Worker 
3328*6dbdd20aSAndroid Build Coastguard Worker     for (protozero::Field f = decoder.ReadField(); f.valid();
3329*6dbdd20aSAndroid Build Coastguard Worker          f = decoder.ReadField()) {
3330*6dbdd20aSAndroid Build Coastguard Worker       if (f.id() == perfetto::protos::pbzero::TestExtension::
3331*6dbdd20aSAndroid Build Coastguard Worker                         FieldMetadata_IntExtensionForTesting::kFieldId) {
3332*6dbdd20aSAndroid Build Coastguard Worker         found_extension = true;
3333*6dbdd20aSAndroid Build Coastguard Worker       }
3334*6dbdd20aSAndroid Build Coastguard Worker     }
3335*6dbdd20aSAndroid Build Coastguard Worker   }
3336*6dbdd20aSAndroid Build Coastguard Worker 
3337*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_extension);
3338*6dbdd20aSAndroid Build Coastguard Worker }
3339*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,InlineTypedExtensionField)3340*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, InlineTypedExtensionField) {
3341*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3342*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3343*6dbdd20aSAndroid Build Coastguard Worker 
3344*6dbdd20aSAndroid Build Coastguard Worker   {
3345*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT(
3346*6dbdd20aSAndroid Build Coastguard Worker         "test", "TestEventWithExtensionArgs",
3347*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::TestExtension::kIntExtensionForTesting,
3348*6dbdd20aSAndroid Build Coastguard Worker         std::vector<int>{42},
3349*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::TestExtension::kUintExtensionForTesting, 42u);
3350*6dbdd20aSAndroid Build Coastguard Worker   }
3351*6dbdd20aSAndroid Build Coastguard Worker 
3352*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
3353*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_GE(raw_trace.size(), 0u);
3354*6dbdd20aSAndroid Build Coastguard Worker 
3355*6dbdd20aSAndroid Build Coastguard Worker   bool found_int_extension = false;
3356*6dbdd20aSAndroid Build Coastguard Worker   bool found_uint_extension = false;
3357*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::pbzero::Trace_Decoder trace(
3358*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<uint8_t*>(raw_trace.data()), raw_trace.size());
3359*6dbdd20aSAndroid Build Coastguard Worker 
3360*6dbdd20aSAndroid Build Coastguard Worker   for (auto it = trace.packet(); it; ++it) {
3361*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::pbzero::TracePacket_Decoder packet(it->data(),
3362*6dbdd20aSAndroid Build Coastguard Worker                                                          it->size());
3363*6dbdd20aSAndroid Build Coastguard Worker 
3364*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
3365*6dbdd20aSAndroid Build Coastguard Worker       continue;
3366*6dbdd20aSAndroid Build Coastguard Worker 
3367*6dbdd20aSAndroid Build Coastguard Worker     auto track_event = packet.track_event();
3368*6dbdd20aSAndroid Build Coastguard Worker     protozero::ProtoDecoder decoder(track_event.data, track_event.size);
3369*6dbdd20aSAndroid Build Coastguard Worker 
3370*6dbdd20aSAndroid Build Coastguard Worker     for (protozero::Field f = decoder.ReadField(); f.valid();
3371*6dbdd20aSAndroid Build Coastguard Worker          f = decoder.ReadField()) {
3372*6dbdd20aSAndroid Build Coastguard Worker       if (f.id() == perfetto::protos::pbzero::TestExtension::
3373*6dbdd20aSAndroid Build Coastguard Worker                         FieldMetadata_IntExtensionForTesting::kFieldId) {
3374*6dbdd20aSAndroid Build Coastguard Worker         found_int_extension = true;
3375*6dbdd20aSAndroid Build Coastguard Worker       } else if (f.id() ==
3376*6dbdd20aSAndroid Build Coastguard Worker                  perfetto::protos::pbzero::TestExtension::
3377*6dbdd20aSAndroid Build Coastguard Worker                      FieldMetadata_UintExtensionForTesting::kFieldId) {
3378*6dbdd20aSAndroid Build Coastguard Worker         found_uint_extension = true;
3379*6dbdd20aSAndroid Build Coastguard Worker       }
3380*6dbdd20aSAndroid Build Coastguard Worker     }
3381*6dbdd20aSAndroid Build Coastguard Worker   }
3382*6dbdd20aSAndroid Build Coastguard Worker 
3383*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_int_extension);
3384*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_uint_extension);
3385*6dbdd20aSAndroid Build Coastguard Worker }
3386*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventInstant)3387*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventInstant) {
3388*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3389*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3390*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3391*6dbdd20aSAndroid Build Coastguard Worker 
3392*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "TestEvent");
3393*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "AnotherEvent");
3394*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3395*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("I:test.TestEvent", "I:test.AnotherEvent"));
3396*6dbdd20aSAndroid Build Coastguard Worker }
3397*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventDefaultGlobalTrack)3398*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventDefaultGlobalTrack) {
3399*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3400*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3401*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3402*6dbdd20aSAndroid Build Coastguard Worker 
3403*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "ThreadEvent");
3404*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "GlobalEvent", perfetto::Track::Global(0u));
3405*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3406*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices,
3407*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("I:test.ThreadEvent", "[track=0]I:test.GlobalEvent"));
3408*6dbdd20aSAndroid Build Coastguard Worker }
3409*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventTrackFromPointer)3410*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventTrackFromPointer) {
3411*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3412*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3413*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3414*6dbdd20aSAndroid Build Coastguard Worker 
3415*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Track parent_track(1);
3416*6dbdd20aSAndroid Build Coastguard Worker   int* ptr = reinterpret_cast<int*>(2);
3417*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "Event",
3418*6dbdd20aSAndroid Build Coastguard Worker                       perfetto::Track::FromPointer(ptr, parent_track));
3419*6dbdd20aSAndroid Build Coastguard Worker 
3420*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Track track(reinterpret_cast<uintptr_t>(ptr), parent_track);
3421*6dbdd20aSAndroid Build Coastguard Worker 
3422*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3423*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("[track=" + std::to_string(track.uuid) +
3424*6dbdd20aSAndroid Build Coastguard Worker                                   "]I:test.Event"));
3425*6dbdd20aSAndroid Build Coastguard Worker }
3426*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventTrackFromThreadScopedPointer)3427*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventTrackFromThreadScopedPointer) {
3428*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3429*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3430*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3431*6dbdd20aSAndroid Build Coastguard Worker 
3432*6dbdd20aSAndroid Build Coastguard Worker   int num = 2;
3433*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "Event0.1");
3434*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "Event0.2");
3435*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "Event1.1", perfetto::Track::ThreadScoped(&num));
3436*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("test", "Event1.2", perfetto::Track::ThreadScoped(&num));
3437*6dbdd20aSAndroid Build Coastguard Worker   std::thread t1([&]() {
3438*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT("test", "Event2.1",
3439*6dbdd20aSAndroid Build Coastguard Worker                         perfetto::Track::ThreadScoped(&num));
3440*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT("test", "Event2.2",
3441*6dbdd20aSAndroid Build Coastguard Worker                         perfetto::Track::ThreadScoped(&num));
3442*6dbdd20aSAndroid Build Coastguard Worker   });
3443*6dbdd20aSAndroid Build Coastguard Worker   t1.join();
3444*6dbdd20aSAndroid Build Coastguard Worker   std::thread t2([&]() {
3445*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT("test", "Event3.1",
3446*6dbdd20aSAndroid Build Coastguard Worker                         perfetto::Track::ThreadScoped(&num));
3447*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT("test", "Event3.2",
3448*6dbdd20aSAndroid Build Coastguard Worker                         perfetto::Track::ThreadScoped(&num));
3449*6dbdd20aSAndroid Build Coastguard Worker   });
3450*6dbdd20aSAndroid Build Coastguard Worker   t2.join();
3451*6dbdd20aSAndroid Build Coastguard Worker 
3452*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
3453*6dbdd20aSAndroid Build Coastguard Worker 
3454*6dbdd20aSAndroid Build Coastguard Worker   std::unordered_map<std::string, uint64_t> track_uuid_map;
3455*6dbdd20aSAndroid Build Coastguard Worker   for (auto packet : trace.packet()) {
3456*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_interned_data()) {
3457*6dbdd20aSAndroid Build Coastguard Worker       for (auto& ename : packet.interned_data().event_names()) {
3458*6dbdd20aSAndroid Build Coastguard Worker         track_uuid_map.emplace(ename.name(), packet.track_event().track_uuid());
3459*6dbdd20aSAndroid Build Coastguard Worker       }
3460*6dbdd20aSAndroid Build Coastguard Worker     }
3461*6dbdd20aSAndroid Build Coastguard Worker   }
3462*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(track_uuid_map.at("Event0.1"), track_uuid_map.at("Event0.2"));
3463*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(track_uuid_map.at("Event1.1"), track_uuid_map.at("Event1.2"));
3464*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(track_uuid_map.at("Event2.1"), track_uuid_map.at("Event2.2"));
3465*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(track_uuid_map.at("Event3.1"), track_uuid_map.at("Event3.2"));
3466*6dbdd20aSAndroid Build Coastguard Worker 
3467*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(4u,
3468*6dbdd20aSAndroid Build Coastguard Worker             (std::unordered_set<uint64_t>{
3469*6dbdd20aSAndroid Build Coastguard Worker                  track_uuid_map.at("Event0.1"), track_uuid_map.at("Event1.1"),
3470*6dbdd20aSAndroid Build Coastguard Worker                  track_uuid_map.at("Event2.1"), track_uuid_map.at("Event3.1")})
3471*6dbdd20aSAndroid Build Coastguard Worker                 .size());
3472*6dbdd20aSAndroid Build Coastguard Worker }
3473*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,FilterDebugAnnotations)3474*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, FilterDebugAnnotations) {
3475*6dbdd20aSAndroid Build Coastguard Worker   for (auto flag : {false, true}) {
3476*6dbdd20aSAndroid Build Coastguard Worker     // Create a new trace session.
3477*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3478*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.set_filter_debug_annotations(flag);
3479*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"test"}, te_cfg);
3480*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
3481*6dbdd20aSAndroid Build Coastguard Worker 
3482*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", "Event1");
3483*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", "Event2", [&](perfetto::EventContext ctx) {
3484*6dbdd20aSAndroid Build Coastguard Worker       ctx.AddDebugAnnotation("debug_name", "debug_value");
3485*6dbdd20aSAndroid Build Coastguard Worker     });
3486*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", "Event3");
3487*6dbdd20aSAndroid Build Coastguard Worker     auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3488*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_EQ(3u, slices.size());
3489*6dbdd20aSAndroid Build Coastguard Worker     if (flag) {
3490*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("B:test.Event2", slices[1]);
3491*6dbdd20aSAndroid Build Coastguard Worker     } else {
3492*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("B:test.Event2(debug_name=(string)debug_value)", slices[1]);
3493*6dbdd20aSAndroid Build Coastguard Worker     }
3494*6dbdd20aSAndroid Build Coastguard Worker   }
3495*6dbdd20aSAndroid Build Coastguard Worker }
3496*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventDebugAnnotations)3497*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventDebugAnnotations) {
3498*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3499*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3500*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3501*6dbdd20aSAndroid Build Coastguard Worker 
3502*6dbdd20aSAndroid Build Coastguard Worker   enum MyEnum : uint32_t { ENUM_FOO, ENUM_BAR };
3503*6dbdd20aSAndroid Build Coastguard Worker   enum MySignedEnum : int32_t { SIGNED_ENUM_FOO = -1, SIGNED_ENUM_BAR };
3504*6dbdd20aSAndroid Build Coastguard Worker   enum class MyClassEnum { VALUE };
3505*6dbdd20aSAndroid Build Coastguard Worker 
3506*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "bool_arg", false);
3507*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "int_arg", -123);
3508*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "uint_arg", 456u);
3509*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "float_arg", 3.14159262f);
3510*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "double_arg", 6.22);
3511*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "str_arg", "hello", "str_arg2",
3512*6dbdd20aSAndroid Build Coastguard Worker                     std::string("tracing"), "str_arg3",
3513*6dbdd20aSAndroid Build Coastguard Worker                     std::string_view("view"));
3514*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "ptr_arg",
3515*6dbdd20aSAndroid Build Coastguard Worker                     reinterpret_cast<void*>(static_cast<intptr_t>(0xbaadf00d)));
3516*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "size_t_arg", size_t{42});
3517*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "ptrdiff_t_arg", ptrdiff_t{-7});
3518*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "enum_arg", ENUM_BAR);
3519*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "signed_enum_arg", SIGNED_ENUM_FOO);
3520*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "class_enum_arg", MyClassEnum::VALUE);
3521*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "traced_value",
3522*6dbdd20aSAndroid Build Coastguard Worker                     [&](perfetto::TracedValue context) {
3523*6dbdd20aSAndroid Build Coastguard Worker                       std::move(context).WriteInt64(42);
3524*6dbdd20aSAndroid Build Coastguard Worker                     });
3525*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", [&](perfetto::EventContext ctx) {
3526*6dbdd20aSAndroid Build Coastguard Worker     ctx.AddDebugAnnotation("debug_annotation", "value");
3527*6dbdd20aSAndroid Build Coastguard Worker   });
3528*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3529*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
3530*6dbdd20aSAndroid Build Coastguard Worker       slices,
3531*6dbdd20aSAndroid Build Coastguard Worker       ElementsAre(
3532*6dbdd20aSAndroid Build Coastguard Worker           "B:test.E(bool_arg=(bool)0)", "B:test.E(int_arg=(int)-123)",
3533*6dbdd20aSAndroid Build Coastguard Worker           "B:test.E(uint_arg=(uint)456)", "B:test.E(float_arg=(double)3.14159)",
3534*6dbdd20aSAndroid Build Coastguard Worker           "B:test.E(double_arg=(double)6.22)",
3535*6dbdd20aSAndroid Build Coastguard Worker           "B:test.E(str_arg=(string)hello,str_arg2=(string)tracing,"
3536*6dbdd20aSAndroid Build Coastguard Worker           "str_arg3=(string)view)",
3537*6dbdd20aSAndroid Build Coastguard Worker           "B:test.E(ptr_arg=(pointer)baadf00d)",
3538*6dbdd20aSAndroid Build Coastguard Worker           "B:test.E(size_t_arg=(uint)42)", "B:test.E(ptrdiff_t_arg=(int)-7)",
3539*6dbdd20aSAndroid Build Coastguard Worker           "B:test.E(enum_arg=(uint)1)", "B:test.E(signed_enum_arg=(int)-1)",
3540*6dbdd20aSAndroid Build Coastguard Worker           "B:test.E(class_enum_arg=(int)0)", "B:test.E(traced_value=(int)42)",
3541*6dbdd20aSAndroid Build Coastguard Worker           "B:test.E(debug_annotation=(string)value)"));
3542*6dbdd20aSAndroid Build Coastguard Worker }
3543*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventCustomDebugAnnotations)3544*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventCustomDebugAnnotations) {
3545*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3546*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3547*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3548*6dbdd20aSAndroid Build Coastguard Worker 
3549*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<MyDebugAnnotation> owned_annotation(new MyDebugAnnotation());
3550*6dbdd20aSAndroid Build Coastguard Worker 
3551*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "custom_arg", MyDebugAnnotation());
3552*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "normal_arg", "x", "custom_arg",
3553*6dbdd20aSAndroid Build Coastguard Worker                     std::move(owned_annotation));
3554*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3555*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
3556*6dbdd20aSAndroid Build Coastguard Worker       slices,
3557*6dbdd20aSAndroid Build Coastguard Worker       ElementsAre(
3558*6dbdd20aSAndroid Build Coastguard Worker           R"(B:test.E(custom_arg=(json){"key": 123}))",
3559*6dbdd20aSAndroid Build Coastguard Worker           R"(B:test.E(normal_arg=(string)x,custom_arg=(json){"key": 123}))"));
3560*6dbdd20aSAndroid Build Coastguard Worker }
3561*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventCustomRawDebugAnnotations)3562*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventCustomRawDebugAnnotations) {
3563*6dbdd20aSAndroid Build Coastguard Worker   // Note: this class is also testing a non-moveable and non-copiable argument.
3564*6dbdd20aSAndroid Build Coastguard Worker   class MyRawDebugAnnotation : public perfetto::DebugAnnotation {
3565*6dbdd20aSAndroid Build Coastguard Worker    public:
3566*6dbdd20aSAndroid Build Coastguard Worker     MyRawDebugAnnotation() { msg_->set_string_value("nested_value"); }
3567*6dbdd20aSAndroid Build Coastguard Worker     ~MyRawDebugAnnotation() = default;
3568*6dbdd20aSAndroid Build Coastguard Worker 
3569*6dbdd20aSAndroid Build Coastguard Worker     // |msg_| already deletes these implicitly, but let's be explicit for safety
3570*6dbdd20aSAndroid Build Coastguard Worker     // against future changes.
3571*6dbdd20aSAndroid Build Coastguard Worker     MyRawDebugAnnotation(const MyRawDebugAnnotation&) = delete;
3572*6dbdd20aSAndroid Build Coastguard Worker     MyRawDebugAnnotation(MyRawDebugAnnotation&&) = delete;
3573*6dbdd20aSAndroid Build Coastguard Worker 
3574*6dbdd20aSAndroid Build Coastguard Worker     void Add(perfetto::protos::pbzero::DebugAnnotation* annotation) const {
3575*6dbdd20aSAndroid Build Coastguard Worker       auto ranges = msg_.GetRanges();
3576*6dbdd20aSAndroid Build Coastguard Worker       annotation->AppendScatteredBytes(
3577*6dbdd20aSAndroid Build Coastguard Worker           perfetto::protos::pbzero::DebugAnnotation::kNestedValueFieldNumber,
3578*6dbdd20aSAndroid Build Coastguard Worker           &ranges[0], ranges.size());
3579*6dbdd20aSAndroid Build Coastguard Worker     }
3580*6dbdd20aSAndroid Build Coastguard Worker 
3581*6dbdd20aSAndroid Build Coastguard Worker    private:
3582*6dbdd20aSAndroid Build Coastguard Worker     mutable protozero::HeapBuffered<
3583*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::DebugAnnotation::NestedValue>
3584*6dbdd20aSAndroid Build Coastguard Worker         msg_;
3585*6dbdd20aSAndroid Build Coastguard Worker   };
3586*6dbdd20aSAndroid Build Coastguard Worker 
3587*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3588*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3589*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3590*6dbdd20aSAndroid Build Coastguard Worker 
3591*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "raw_arg", MyRawDebugAnnotation());
3592*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "plain_arg", 42, "raw_arg",
3593*6dbdd20aSAndroid Build Coastguard Worker                     MyRawDebugAnnotation());
3594*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3595*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
3596*6dbdd20aSAndroid Build Coastguard Worker       slices,
3597*6dbdd20aSAndroid Build Coastguard Worker       ElementsAre("B:test.E(raw_arg=(nested)nested_value)",
3598*6dbdd20aSAndroid Build Coastguard Worker                   "B:test.E(plain_arg=(int)42,raw_arg=(nested)nested_value)"));
3599*6dbdd20aSAndroid Build Coastguard Worker }
3600*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ManyDebugAnnotations)3601*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ManyDebugAnnotations) {
3602*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3603*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3604*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3605*6dbdd20aSAndroid Build Coastguard Worker 
3606*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "E", "arg1", 1, "arg2", 2, "arg3", 3);
3607*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3608*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices,
3609*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:test.E(arg1=(int)1,arg2=(int)2,arg3=(int)3)"));
3610*6dbdd20aSAndroid Build Coastguard Worker }
3611*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,DebugAnnotationAndLambda)3612*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, DebugAnnotationAndLambda) {
3613*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3614*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3615*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3616*6dbdd20aSAndroid Build Coastguard Worker 
3617*6dbdd20aSAndroid Build Coastguard Worker   enum MyEnum : uint32_t { ENUM_FOO, ENUM_BAR };
3618*6dbdd20aSAndroid Build Coastguard Worker   enum MySignedEnum : int32_t { SIGNED_ENUM_FOO = -1, SIGNED_ENUM_BAR };
3619*6dbdd20aSAndroid Build Coastguard Worker   enum class MyClassEnum { VALUE };
3620*6dbdd20aSAndroid Build Coastguard Worker 
3621*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN(
3622*6dbdd20aSAndroid Build Coastguard Worker       "test", "E", "key", "value", [](perfetto::EventContext ctx) {
3623*6dbdd20aSAndroid Build Coastguard Worker         ctx.event()->set_log_message()->set_source_location_iid(42);
3624*6dbdd20aSAndroid Build Coastguard Worker       });
3625*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
3626*6dbdd20aSAndroid Build Coastguard Worker 
3627*6dbdd20aSAndroid Build Coastguard Worker   bool found_args = false;
3628*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
3629*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
3630*6dbdd20aSAndroid Build Coastguard Worker       continue;
3631*6dbdd20aSAndroid Build Coastguard Worker     const auto& track_event = packet.track_event();
3632*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.type() !=
3633*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::gen::TrackEvent::TYPE_SLICE_BEGIN)
3634*6dbdd20aSAndroid Build Coastguard Worker       continue;
3635*6dbdd20aSAndroid Build Coastguard Worker 
3636*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(track_event.has_log_message());
3637*6dbdd20aSAndroid Build Coastguard Worker     const auto& log = track_event.log_message();
3638*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(42u, log.source_location_iid());
3639*6dbdd20aSAndroid Build Coastguard Worker 
3640*6dbdd20aSAndroid Build Coastguard Worker     const auto& dbg = track_event.debug_annotations()[0];
3641*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ("value", dbg.string_value());
3642*6dbdd20aSAndroid Build Coastguard Worker 
3643*6dbdd20aSAndroid Build Coastguard Worker     found_args = true;
3644*6dbdd20aSAndroid Build Coastguard Worker   }
3645*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_args);
3646*6dbdd20aSAndroid Build Coastguard Worker }
3647*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ProtoInsideDebugAnnotation)3648*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ProtoInsideDebugAnnotation) {
3649*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
3650*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3651*6dbdd20aSAndroid Build Coastguard Worker 
3652*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT(
3653*6dbdd20aSAndroid Build Coastguard Worker       "test", "E", "key",
3654*6dbdd20aSAndroid Build Coastguard Worker       [](perfetto::TracedProto<perfetto::protos::pbzero::LogMessage> ctx) {
3655*6dbdd20aSAndroid Build Coastguard Worker         ctx->set_source_location_iid(42);
3656*6dbdd20aSAndroid Build Coastguard Worker       });
3657*6dbdd20aSAndroid Build Coastguard Worker 
3658*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
3659*6dbdd20aSAndroid Build Coastguard Worker 
3660*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> interned_debug_annotation_names;
3661*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> interned_debug_annotation_proto_type_names;
3662*6dbdd20aSAndroid Build Coastguard Worker 
3663*6dbdd20aSAndroid Build Coastguard Worker   bool found_args = false;
3664*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
3665*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_interned_data()) {
3666*6dbdd20aSAndroid Build Coastguard Worker       for (const auto& interned_name :
3667*6dbdd20aSAndroid Build Coastguard Worker            packet.interned_data().debug_annotation_names()) {
3668*6dbdd20aSAndroid Build Coastguard Worker         interned_debug_annotation_names.push_back(interned_name.name());
3669*6dbdd20aSAndroid Build Coastguard Worker       }
3670*6dbdd20aSAndroid Build Coastguard Worker       for (const auto& interned_type_name :
3671*6dbdd20aSAndroid Build Coastguard Worker            packet.interned_data().debug_annotation_value_type_names()) {
3672*6dbdd20aSAndroid Build Coastguard Worker         interned_debug_annotation_proto_type_names.push_back(
3673*6dbdd20aSAndroid Build Coastguard Worker             interned_type_name.name());
3674*6dbdd20aSAndroid Build Coastguard Worker       }
3675*6dbdd20aSAndroid Build Coastguard Worker     }
3676*6dbdd20aSAndroid Build Coastguard Worker 
3677*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_event())
3678*6dbdd20aSAndroid Build Coastguard Worker       continue;
3679*6dbdd20aSAndroid Build Coastguard Worker     const auto& track_event = packet.track_event();
3680*6dbdd20aSAndroid Build Coastguard Worker     if (track_event.type() != perfetto::protos::gen::TrackEvent::TYPE_INSTANT) {
3681*6dbdd20aSAndroid Build Coastguard Worker       continue;
3682*6dbdd20aSAndroid Build Coastguard Worker     }
3683*6dbdd20aSAndroid Build Coastguard Worker 
3684*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(track_event.debug_annotations_size(), 1);
3685*6dbdd20aSAndroid Build Coastguard Worker     found_args = true;
3686*6dbdd20aSAndroid Build Coastguard Worker   }
3687*6dbdd20aSAndroid Build Coastguard Worker   // TODO(altimin): Use DebugAnnotationParser here to parse the debug
3688*6dbdd20aSAndroid Build Coastguard Worker   // annotations.
3689*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_args);
3690*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(interned_debug_annotation_names,
3691*6dbdd20aSAndroid Build Coastguard Worker               testing::UnorderedElementsAre("key"));
3692*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(interned_debug_annotation_proto_type_names,
3693*6dbdd20aSAndroid Build Coastguard Worker               testing::UnorderedElementsAre(".perfetto.protos.LogMessage"));
3694*6dbdd20aSAndroid Build Coastguard Worker }
3695*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventComputedName)3696*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventComputedName) {
3697*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
3698*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
3699*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
3700*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
3701*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
3702*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
3703*6dbdd20aSAndroid Build Coastguard Worker 
3704*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3705*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
3706*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3707*6dbdd20aSAndroid Build Coastguard Worker 
3708*6dbdd20aSAndroid Build Coastguard Worker   // New macros require perfetto::StaticString{} annotation.
3709*6dbdd20aSAndroid Build Coastguard Worker   for (int i = 0; i < 3; i++)
3710*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", perfetto::StaticString{i % 2 ? "Odd" : "Even"});
3711*6dbdd20aSAndroid Build Coastguard Worker 
3712*6dbdd20aSAndroid Build Coastguard Worker   // Legacy macros assume all arguments are static strings.
3713*6dbdd20aSAndroid Build Coastguard Worker   for (int i = 0; i < 3; i++)
3714*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN0("test", i % 2 ? "Odd" : "Even");
3715*6dbdd20aSAndroid Build Coastguard Worker 
3716*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3717*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.Even", "B:test.Odd", "B:test.Even",
3718*6dbdd20aSAndroid Build Coastguard Worker                                   "B:test.Even", "B:test.Odd", "B:test.Even"));
3719*6dbdd20aSAndroid Build Coastguard Worker }
3720*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventEventNameDynamicString)3721*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventEventNameDynamicString) {
3722*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3723*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
3724*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3725*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", perfetto::DynamicString{std::string("Event1")});
3726*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", perfetto::DynamicString{std::string("Event2")});
3727*6dbdd20aSAndroid Build Coastguard Worker 
3728*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT0("foo", TRACE_STR_COPY(std::string("Event3")));
3729*6dbdd20aSAndroid Build Coastguard Worker   const char* event4 = "Event4";
3730*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT0("foo", event4);
3731*6dbdd20aSAndroid Build Coastguard Worker 
3732*6dbdd20aSAndroid Build Coastguard Worker   // Ensure that event-name is not emitted in case of `_END` events.
3733*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(
3734*6dbdd20aSAndroid Build Coastguard Worker       TraceForCategory, "foo", perfetto::DynamicString{std::string("Event5")},
3735*6dbdd20aSAndroid Build Coastguard Worker       ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END);
3736*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(
3737*6dbdd20aSAndroid Build Coastguard Worker       TraceForCategory, "foo", perfetto::StaticString{"Event6"},
3738*6dbdd20aSAndroid Build Coastguard Worker       ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END);
3739*6dbdd20aSAndroid Build Coastguard Worker 
3740*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3741*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(6u, slices.size());
3742*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event1", slices[0]);
3743*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event2", slices[1]);
3744*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event3", slices[2]);
3745*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event4", slices[3]);
3746*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("E", slices[4]);
3747*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("E", slices[5]);
3748*6dbdd20aSAndroid Build Coastguard Worker }
3749*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventDynamicStringInDebugArgs)3750*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventDynamicStringInDebugArgs) {
3751*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
3752*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3753*6dbdd20aSAndroid Build Coastguard Worker 
3754*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT1("foo", "Event1", "arg1",
3755*6dbdd20aSAndroid Build Coastguard Worker                TRACE_STR_COPY(std::string("arg1_value1")));
3756*6dbdd20aSAndroid Build Coastguard Worker   const char* value2 = "arg1_value2";
3757*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT1("foo", "Event2", "arg1", value2);
3758*6dbdd20aSAndroid Build Coastguard Worker   const char* value4 = "arg1_value4";
3759*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT1("foo", "Event3", "arg1",
3760*6dbdd20aSAndroid Build Coastguard Worker                perfetto::DynamicString(std::string("arg1_value3")));
3761*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT1("foo", "Event4", "arg1", perfetto::StaticString(value4));
3762*6dbdd20aSAndroid Build Coastguard Worker 
3763*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Event5", "arg1",
3764*6dbdd20aSAndroid Build Coastguard Worker                     TRACE_STR_COPY(std::string("arg1_value5")));
3765*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Event6", "arg1",
3766*6dbdd20aSAndroid Build Coastguard Worker                     perfetto::DynamicString(std::string("arg1_value6")));
3767*6dbdd20aSAndroid Build Coastguard Worker   const char* value7 = "arg1_value7";
3768*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Event7", "arg1", perfetto::StaticString(value7));
3769*6dbdd20aSAndroid Build Coastguard Worker   const char* arg_name = "new_arg1";
3770*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Event8", perfetto::DynamicString{arg_name}, 5);
3771*6dbdd20aSAndroid Build Coastguard Worker 
3772*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3773*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(8u, slices.size());
3774*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event1(arg1=(string)arg1_value1)", slices[0]);
3775*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event2(arg1=(string)arg1_value2)", slices[1]);
3776*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event3(arg1=(string)arg1_value3)", slices[2]);
3777*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event4(arg1=(string)arg1_value4)", slices[3]);
3778*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event5(arg1=(string)arg1_value5)", slices[4]);
3779*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event6(arg1=(string)arg1_value6)", slices[5]);
3780*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event7(arg1=(string)arg1_value7)", slices[6]);
3781*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event8(new_arg1=(int)5)", slices[7]);
3782*6dbdd20aSAndroid Build Coastguard Worker }
3783*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventLegacyNullStringInArgs)3784*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventLegacyNullStringInArgs) {
3785*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
3786*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3787*6dbdd20aSAndroid Build Coastguard Worker 
3788*6dbdd20aSAndroid Build Coastguard Worker   const char* null_str = nullptr;
3789*6dbdd20aSAndroid Build Coastguard Worker 
3790*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT1("foo", "Event1", "arg1", null_str);
3791*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT1("foo", "Event2", "arg1", TRACE_STR_COPY(null_str));
3792*6dbdd20aSAndroid Build Coastguard Worker 
3793*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3794*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(2u, slices.size());
3795*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event1(arg1=(string)NULL)", slices[0]);
3796*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("B:foo.Event2(arg1=(string)NULL)", slices[1]);
3797*6dbdd20aSAndroid Build Coastguard Worker }
3798*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,FilterDynamicEventName)3799*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, FilterDynamicEventName) {
3800*6dbdd20aSAndroid Build Coastguard Worker   for (auto filter_dynamic_names : {false, true}) {
3801*6dbdd20aSAndroid Build Coastguard Worker     // Create a new trace session.
3802*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3803*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.set_filter_dynamic_event_names(filter_dynamic_names);
3804*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"test"}, te_cfg);
3805*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
3806*6dbdd20aSAndroid Build Coastguard Worker 
3807*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", "Event1");
3808*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", perfetto::DynamicString("Event2"));
3809*6dbdd20aSAndroid Build Coastguard Worker     const char* event3 = "Event3";
3810*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", perfetto::StaticString(event3));
3811*6dbdd20aSAndroid Build Coastguard Worker     auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3812*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_EQ(3u, slices.size());
3813*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ("B:test.Event1", slices[0]);
3814*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(filter_dynamic_names ? "B:test.FILTERED" : "B:test.Event2",
3815*6dbdd20aSAndroid Build Coastguard Worker               slices[1]);
3816*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ("B:test.Event3", slices[2]);
3817*6dbdd20aSAndroid Build Coastguard Worker   }
3818*6dbdd20aSAndroid Build Coastguard Worker }
3819*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventArgumentsNotEvaluatedWhenDisabled)3820*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventArgumentsNotEvaluatedWhenDisabled) {
3821*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
3822*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
3823*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
3824*6dbdd20aSAndroid Build Coastguard Worker 
3825*6dbdd20aSAndroid Build Coastguard Worker   bool called = false;
3826*6dbdd20aSAndroid Build Coastguard Worker   auto ArgumentFunction = [&] {
3827*6dbdd20aSAndroid Build Coastguard Worker     called = true;
3828*6dbdd20aSAndroid Build Coastguard Worker     return 123;
3829*6dbdd20aSAndroid Build Coastguard Worker   };
3830*6dbdd20aSAndroid Build Coastguard Worker 
3831*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "DisabledEvent", "arg", ArgumentFunction());
3832*6dbdd20aSAndroid Build Coastguard Worker   { TRACE_EVENT("test", "DisabledScopedEvent", "arg", ArgumentFunction()); }
3833*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Flush();
3834*6dbdd20aSAndroid Build Coastguard Worker 
3835*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
3836*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(called);
3837*6dbdd20aSAndroid Build Coastguard Worker 
3838*6dbdd20aSAndroid Build Coastguard Worker   ArgumentFunction();
3839*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(called);
3840*6dbdd20aSAndroid Build Coastguard Worker }
3841*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventConfig)3842*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventConfig) {
3843*6dbdd20aSAndroid Build Coastguard Worker   auto check_config = [&](perfetto::protos::gen::TrackEventConfig te_cfg) {
3844*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TraceConfig cfg;
3845*6dbdd20aSAndroid Build Coastguard Worker     cfg.set_duration_ms(500);
3846*6dbdd20aSAndroid Build Coastguard Worker     cfg.add_buffers()->set_size_kb(1024);
3847*6dbdd20aSAndroid Build Coastguard Worker     auto* ds_cfg = cfg.add_data_sources()->mutable_config();
3848*6dbdd20aSAndroid Build Coastguard Worker     ds_cfg->set_name("track_event");
3849*6dbdd20aSAndroid Build Coastguard Worker     ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
3850*6dbdd20aSAndroid Build Coastguard Worker 
3851*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTrace(cfg);
3852*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
3853*6dbdd20aSAndroid Build Coastguard Worker 
3854*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo", "FooEvent");
3855*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("bar", "BarEvent");
3856*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("foo,bar", "MultiFooBar");
3857*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("baz,bar,quux", "MultiBar");
3858*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("red,green,blue,foo", "MultiFoo");
3859*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("red,green,blue,yellow", "MultiNone");
3860*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("cat", "SlowEvent");
3861*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("cat.verbose", "DebugEvent");
3862*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", "TagEvent");
3863*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN(TRACE_DISABLED_BY_DEFAULT("cat"), "SlowDisabledEvent");
3864*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("dynamic,foo", "DynamicGroupFooEvent");
3865*6dbdd20aSAndroid Build Coastguard Worker     perfetto::DynamicCategory dyn{"dynamic,bar"};
3866*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN(dyn, "DynamicGroupBarEvent");
3867*6dbdd20aSAndroid Build Coastguard Worker 
3868*6dbdd20aSAndroid Build Coastguard Worker     auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
3869*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->session.reset();
3870*6dbdd20aSAndroid Build Coastguard Worker     return slices;
3871*6dbdd20aSAndroid Build Coastguard Worker   };
3872*6dbdd20aSAndroid Build Coastguard Worker 
3873*6dbdd20aSAndroid Build Coastguard Worker   // Empty config should enable all categories except slow ones.
3874*6dbdd20aSAndroid Build Coastguard Worker   {
3875*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3876*6dbdd20aSAndroid Build Coastguard Worker     auto slices = check_config(te_cfg);
3877*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(
3878*6dbdd20aSAndroid Build Coastguard Worker         slices,
3879*6dbdd20aSAndroid Build Coastguard Worker         ElementsAre("B:foo.FooEvent", "B:bar.BarEvent", "B:foo,bar.MultiFooBar",
3880*6dbdd20aSAndroid Build Coastguard Worker                     "B:baz,bar,quux.MultiBar", "B:red,green,blue,foo.MultiFoo",
3881*6dbdd20aSAndroid Build Coastguard Worker                     "B:red,green,blue,yellow.MultiNone", "B:test.TagEvent",
3882*6dbdd20aSAndroid Build Coastguard Worker                     "B:$dynamic,$foo.DynamicGroupFooEvent",
3883*6dbdd20aSAndroid Build Coastguard Worker                     "B:$dynamic,$bar.DynamicGroupBarEvent"));
3884*6dbdd20aSAndroid Build Coastguard Worker   }
3885*6dbdd20aSAndroid Build Coastguard Worker 
3886*6dbdd20aSAndroid Build Coastguard Worker   // Enable exactly one category.
3887*6dbdd20aSAndroid Build Coastguard Worker   {
3888*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3889*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_disabled_categories("*");
3890*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_categories("foo");
3891*6dbdd20aSAndroid Build Coastguard Worker     auto slices = check_config(te_cfg);
3892*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(slices, ElementsAre("B:foo.FooEvent", "B:foo,bar.MultiFooBar",
3893*6dbdd20aSAndroid Build Coastguard Worker                                     "B:red,green,blue,foo.MultiFoo",
3894*6dbdd20aSAndroid Build Coastguard Worker                                     "B:$dynamic,$foo.DynamicGroupFooEvent"));
3895*6dbdd20aSAndroid Build Coastguard Worker   }
3896*6dbdd20aSAndroid Build Coastguard Worker 
3897*6dbdd20aSAndroid Build Coastguard Worker   // Enable exactly one dynamic category.
3898*6dbdd20aSAndroid Build Coastguard Worker   {
3899*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3900*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_disabled_categories("*");
3901*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_categories("dynamic");
3902*6dbdd20aSAndroid Build Coastguard Worker     auto slices = check_config(te_cfg);
3903*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(slices, ElementsAre("B:$dynamic,$foo.DynamicGroupFooEvent",
3904*6dbdd20aSAndroid Build Coastguard Worker                                     "B:$dynamic,$bar.DynamicGroupBarEvent"));
3905*6dbdd20aSAndroid Build Coastguard Worker   }
3906*6dbdd20aSAndroid Build Coastguard Worker 
3907*6dbdd20aSAndroid Build Coastguard Worker   // Enable two categories.
3908*6dbdd20aSAndroid Build Coastguard Worker   {
3909*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3910*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_disabled_categories("*");
3911*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_categories("foo");
3912*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_categories("baz");
3913*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_categories("bar");
3914*6dbdd20aSAndroid Build Coastguard Worker     auto slices = check_config(te_cfg);
3915*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(
3916*6dbdd20aSAndroid Build Coastguard Worker         slices,
3917*6dbdd20aSAndroid Build Coastguard Worker         ElementsAre("B:foo.FooEvent", "B:bar.BarEvent", "B:foo,bar.MultiFooBar",
3918*6dbdd20aSAndroid Build Coastguard Worker                     "B:baz,bar,quux.MultiBar", "B:red,green,blue,foo.MultiFoo",
3919*6dbdd20aSAndroid Build Coastguard Worker                     "B:$dynamic,$foo.DynamicGroupFooEvent",
3920*6dbdd20aSAndroid Build Coastguard Worker                     "B:$dynamic,$bar.DynamicGroupBarEvent"));
3921*6dbdd20aSAndroid Build Coastguard Worker   }
3922*6dbdd20aSAndroid Build Coastguard Worker 
3923*6dbdd20aSAndroid Build Coastguard Worker   // Enabling all categories with a pattern doesn't enable slow ones.
3924*6dbdd20aSAndroid Build Coastguard Worker   {
3925*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3926*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_categories("*");
3927*6dbdd20aSAndroid Build Coastguard Worker     auto slices = check_config(te_cfg);
3928*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(
3929*6dbdd20aSAndroid Build Coastguard Worker         slices,
3930*6dbdd20aSAndroid Build Coastguard Worker         ElementsAre("B:foo.FooEvent", "B:bar.BarEvent", "B:foo,bar.MultiFooBar",
3931*6dbdd20aSAndroid Build Coastguard Worker                     "B:baz,bar,quux.MultiBar", "B:red,green,blue,foo.MultiFoo",
3932*6dbdd20aSAndroid Build Coastguard Worker                     "B:red,green,blue,yellow.MultiNone", "B:test.TagEvent",
3933*6dbdd20aSAndroid Build Coastguard Worker                     "B:$dynamic,$foo.DynamicGroupFooEvent",
3934*6dbdd20aSAndroid Build Coastguard Worker                     "B:$dynamic,$bar.DynamicGroupBarEvent"));
3935*6dbdd20aSAndroid Build Coastguard Worker   }
3936*6dbdd20aSAndroid Build Coastguard Worker 
3937*6dbdd20aSAndroid Build Coastguard Worker   // Enable with a pattern.
3938*6dbdd20aSAndroid Build Coastguard Worker   {
3939*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3940*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_disabled_categories("*");
3941*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_categories("fo*");
3942*6dbdd20aSAndroid Build Coastguard Worker     auto slices = check_config(te_cfg);
3943*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(slices, ElementsAre("B:foo.FooEvent", "B:foo,bar.MultiFooBar",
3944*6dbdd20aSAndroid Build Coastguard Worker                                     "B:red,green,blue,foo.MultiFoo",
3945*6dbdd20aSAndroid Build Coastguard Worker                                     "B:$dynamic,$foo.DynamicGroupFooEvent"));
3946*6dbdd20aSAndroid Build Coastguard Worker   }
3947*6dbdd20aSAndroid Build Coastguard Worker 
3948*6dbdd20aSAndroid Build Coastguard Worker   // Enable with a tag.
3949*6dbdd20aSAndroid Build Coastguard Worker   {
3950*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3951*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_disabled_categories("*");
3952*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_tags("tag");
3953*6dbdd20aSAndroid Build Coastguard Worker     auto slices = check_config(te_cfg);
3954*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(slices, ElementsAre("B:test.TagEvent"));
3955*6dbdd20aSAndroid Build Coastguard Worker   }
3956*6dbdd20aSAndroid Build Coastguard Worker 
3957*6dbdd20aSAndroid Build Coastguard Worker   // Enable just slow categories.
3958*6dbdd20aSAndroid Build Coastguard Worker   {
3959*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3960*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_disabled_categories("*");
3961*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_tags("slow");
3962*6dbdd20aSAndroid Build Coastguard Worker     auto slices = check_config(te_cfg);
3963*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(slices,
3964*6dbdd20aSAndroid Build Coastguard Worker                 ElementsAre("B:cat.SlowEvent",
3965*6dbdd20aSAndroid Build Coastguard Worker                             "B:disabled-by-default-cat.SlowDisabledEvent"));
3966*6dbdd20aSAndroid Build Coastguard Worker   }
3967*6dbdd20aSAndroid Build Coastguard Worker 
3968*6dbdd20aSAndroid Build Coastguard Worker   // Enable all legacy disabled-by-default categories by a pattern
3969*6dbdd20aSAndroid Build Coastguard Worker   {
3970*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3971*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_disabled_categories("*");
3972*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_categories("disabled-by-default-*");
3973*6dbdd20aSAndroid Build Coastguard Worker     auto slices = check_config(te_cfg);
3974*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(slices,
3975*6dbdd20aSAndroid Build Coastguard Worker                 ElementsAre("B:disabled-by-default-cat.SlowDisabledEvent"));
3976*6dbdd20aSAndroid Build Coastguard Worker   }
3977*6dbdd20aSAndroid Build Coastguard Worker 
3978*6dbdd20aSAndroid Build Coastguard Worker   // Enable everything including slow/debug categories.
3979*6dbdd20aSAndroid Build Coastguard Worker   {
3980*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
3981*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_categories("*");
3982*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_tags("slow");
3983*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_tags("debug");
3984*6dbdd20aSAndroid Build Coastguard Worker     auto slices = check_config(te_cfg);
3985*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(
3986*6dbdd20aSAndroid Build Coastguard Worker         slices,
3987*6dbdd20aSAndroid Build Coastguard Worker         ElementsAre("B:foo.FooEvent", "B:bar.BarEvent", "B:foo,bar.MultiFooBar",
3988*6dbdd20aSAndroid Build Coastguard Worker                     "B:baz,bar,quux.MultiBar", "B:red,green,blue,foo.MultiFoo",
3989*6dbdd20aSAndroid Build Coastguard Worker                     "B:red,green,blue,yellow.MultiNone", "B:cat.SlowEvent",
3990*6dbdd20aSAndroid Build Coastguard Worker                     "B:cat.verbose.DebugEvent", "B:test.TagEvent",
3991*6dbdd20aSAndroid Build Coastguard Worker                     "B:disabled-by-default-cat.SlowDisabledEvent",
3992*6dbdd20aSAndroid Build Coastguard Worker                     "B:$dynamic,$foo.DynamicGroupFooEvent",
3993*6dbdd20aSAndroid Build Coastguard Worker                     "B:$dynamic,$bar.DynamicGroupBarEvent"));
3994*6dbdd20aSAndroid Build Coastguard Worker   }
3995*6dbdd20aSAndroid Build Coastguard Worker }
3996*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,OneDataSourceOneEvent)3997*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, OneDataSourceOneEvent) {
3998*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
3999*6dbdd20aSAndroid Build Coastguard Worker 
4000*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
4001*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4002*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
4003*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4004*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4005*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4006*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_legacy_config("test config");
4007*6dbdd20aSAndroid Build Coastguard Worker 
4008*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4009*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4010*6dbdd20aSAndroid Build Coastguard Worker 
4011*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace([](MockDataSource::TraceContext) {
4012*6dbdd20aSAndroid Build Coastguard Worker     FAIL() << "Should not be called because the trace was not started";
4013*6dbdd20aSAndroid Build Coastguard Worker   });
4014*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::CallIfEnabled([](uint32_t) {
4015*6dbdd20aSAndroid Build Coastguard Worker     FAIL() << "Should not be called because the trace was not started";
4016*6dbdd20aSAndroid Build Coastguard Worker   });
4017*6dbdd20aSAndroid Build Coastguard Worker 
4018*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->Start();
4019*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_setup.Wait();
4020*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(data_source->config.legacy_config(), "test config");
4021*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_start.Wait();
4022*6dbdd20aSAndroid Build Coastguard Worker 
4023*6dbdd20aSAndroid Build Coastguard Worker   // Emit one trace event.
4024*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<int> trace_lambda_calls{0};
4025*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace(
4026*6dbdd20aSAndroid Build Coastguard Worker       [&trace_lambda_calls](MockDataSource::TraceContext ctx) {
4027*6dbdd20aSAndroid Build Coastguard Worker         auto packet = ctx.NewTracePacket();
4028*6dbdd20aSAndroid Build Coastguard Worker         packet->set_timestamp(42);
4029*6dbdd20aSAndroid Build Coastguard Worker         packet->set_for_testing()->set_str("event 1");
4030*6dbdd20aSAndroid Build Coastguard Worker         trace_lambda_calls++;
4031*6dbdd20aSAndroid Build Coastguard Worker         packet->Finalize();
4032*6dbdd20aSAndroid Build Coastguard Worker 
4033*6dbdd20aSAndroid Build Coastguard Worker         // The SMB scraping logic will skip the last packet because it cannot
4034*6dbdd20aSAndroid Build Coastguard Worker         // guarantee it's finalized. Create an empty packet so we get the
4035*6dbdd20aSAndroid Build Coastguard Worker         // previous one and this empty one is ignored.
4036*6dbdd20aSAndroid Build Coastguard Worker         packet = ctx.NewTracePacket();
4037*6dbdd20aSAndroid Build Coastguard Worker       });
4038*6dbdd20aSAndroid Build Coastguard Worker 
4039*6dbdd20aSAndroid Build Coastguard Worker   uint32_t active_instances = 0;
4040*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::CallIfEnabled([&active_instances](uint32_t instances) {
4041*6dbdd20aSAndroid Build Coastguard Worker     active_instances = instances;
4042*6dbdd20aSAndroid Build Coastguard Worker   });
4043*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(1u, active_instances);
4044*6dbdd20aSAndroid Build Coastguard Worker 
4045*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop.Wait();
4046*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->on_stop.Wait();
4047*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(trace_lambda_calls, 1);
4048*6dbdd20aSAndroid Build Coastguard Worker 
4049*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace([](MockDataSource::TraceContext) {
4050*6dbdd20aSAndroid Build Coastguard Worker     FAIL() << "Should not be called because the trace is now stopped";
4051*6dbdd20aSAndroid Build Coastguard Worker   });
4052*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::CallIfEnabled([](uint32_t) {
4053*6dbdd20aSAndroid Build Coastguard Worker     FAIL() << "Should not be called because the trace is now stopped";
4054*6dbdd20aSAndroid Build Coastguard Worker   });
4055*6dbdd20aSAndroid Build Coastguard Worker 
4056*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
4057*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_GE(raw_trace.size(), 0u);
4058*6dbdd20aSAndroid Build Coastguard Worker 
4059*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace trace;
4060*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
4061*6dbdd20aSAndroid Build Coastguard Worker   bool test_packet_found = false;
4062*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
4063*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_for_testing())
4064*6dbdd20aSAndroid Build Coastguard Worker       continue;
4065*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(test_packet_found);
4066*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(packet.timestamp(), 42U);
4067*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(packet.for_testing().str(), "event 1");
4068*6dbdd20aSAndroid Build Coastguard Worker     test_packet_found = true;
4069*6dbdd20aSAndroid Build Coastguard Worker   }
4070*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(test_packet_found);
4071*6dbdd20aSAndroid Build Coastguard Worker }
4072*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ReentrantTracing)4073*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ReentrantTracing) {
4074*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
4075*6dbdd20aSAndroid Build Coastguard Worker 
4076*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
4077*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4078*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
4079*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4080*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4081*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4082*6dbdd20aSAndroid Build Coastguard Worker 
4083*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4084*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4085*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->Start();
4086*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_start.Wait();
4087*6dbdd20aSAndroid Build Coastguard Worker 
4088*6dbdd20aSAndroid Build Coastguard Worker   // Check that only one level of trace lambda calls is allowed.
4089*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<int> trace_lambda_calls{0};
4090*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace([&trace_lambda_calls](MockDataSource::TraceContext) {
4091*6dbdd20aSAndroid Build Coastguard Worker     trace_lambda_calls++;
4092*6dbdd20aSAndroid Build Coastguard Worker     MockDataSource::Trace([&trace_lambda_calls](MockDataSource::TraceContext) {
4093*6dbdd20aSAndroid Build Coastguard Worker       trace_lambda_calls++;
4094*6dbdd20aSAndroid Build Coastguard Worker     });
4095*6dbdd20aSAndroid Build Coastguard Worker   });
4096*6dbdd20aSAndroid Build Coastguard Worker 
4097*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4098*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(trace_lambda_calls, 1);
4099*6dbdd20aSAndroid Build Coastguard Worker }
4100*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ConsumerFlush)4101*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ConsumerFlush) {
4102*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
4103*6dbdd20aSAndroid Build Coastguard Worker 
4104*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
4105*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4106*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4107*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4108*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4109*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_legacy_config("test config");
4110*6dbdd20aSAndroid Build Coastguard Worker 
4111*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4112*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4113*6dbdd20aSAndroid Build Coastguard Worker 
4114*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->Start();
4115*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_start.Wait();
4116*6dbdd20aSAndroid Build Coastguard Worker 
4117*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace([&](MockDataSource::TraceContext ctx) {
4118*6dbdd20aSAndroid Build Coastguard Worker     auto packet = ctx.NewTracePacket();
4119*6dbdd20aSAndroid Build Coastguard Worker     packet->set_timestamp(42);
4120*6dbdd20aSAndroid Build Coastguard Worker     packet->set_for_testing()->set_str("flushed event");
4121*6dbdd20aSAndroid Build Coastguard Worker     packet->Finalize();
4122*6dbdd20aSAndroid Build Coastguard Worker 
4123*6dbdd20aSAndroid Build Coastguard Worker     // The SMB scraping logic will skip the last packet because it cannot
4124*6dbdd20aSAndroid Build Coastguard Worker     // guarantee it's finalized. Create an empty packet so we get the
4125*6dbdd20aSAndroid Build Coastguard Worker     // previous one and this empty one is ignored.
4126*6dbdd20aSAndroid Build Coastguard Worker     packet = ctx.NewTracePacket();
4127*6dbdd20aSAndroid Build Coastguard Worker   });
4128*6dbdd20aSAndroid Build Coastguard Worker 
4129*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
4130*6dbdd20aSAndroid Build Coastguard Worker 
4131*6dbdd20aSAndroid Build Coastguard Worker   bool test_packet_found = false;
4132*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
4133*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_for_testing())
4134*6dbdd20aSAndroid Build Coastguard Worker       continue;
4135*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(test_packet_found);
4136*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(packet.timestamp(), 42U);
4137*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(packet.for_testing().str(), "flushed event");
4138*6dbdd20aSAndroid Build Coastguard Worker     test_packet_found = true;
4139*6dbdd20aSAndroid Build Coastguard Worker   }
4140*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(test_packet_found);
4141*6dbdd20aSAndroid Build Coastguard Worker }
4142*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,WithBatching)4143*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, WithBatching) {
4144*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
4145*6dbdd20aSAndroid Build Coastguard Worker 
4146*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
4147*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4148*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
4149*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4150*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4151*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4152*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_legacy_config("test config");
4153*6dbdd20aSAndroid Build Coastguard Worker 
4154*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4155*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4156*6dbdd20aSAndroid Build Coastguard Worker 
4157*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->Start();
4158*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_setup.Wait();
4159*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_start.Wait();
4160*6dbdd20aSAndroid Build Coastguard Worker 
4161*6dbdd20aSAndroid Build Coastguard Worker   std::stringstream first_large_message;
4162*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < 512; i++)
4163*6dbdd20aSAndroid Build Coastguard Worker     first_large_message << i << ". Something wicked this way comes. ";
4164*6dbdd20aSAndroid Build Coastguard Worker   auto first_large_message_str = first_large_message.str();
4165*6dbdd20aSAndroid Build Coastguard Worker 
4166*6dbdd20aSAndroid Build Coastguard Worker   // Emit one trace event before we begin batching.
4167*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace(
4168*6dbdd20aSAndroid Build Coastguard Worker       [&first_large_message_str](MockDataSource::TraceContext ctx) {
4169*6dbdd20aSAndroid Build Coastguard Worker         auto packet = ctx.NewTracePacket();
4170*6dbdd20aSAndroid Build Coastguard Worker         packet->set_timestamp(42);
4171*6dbdd20aSAndroid Build Coastguard Worker         packet->set_for_testing()->set_str(first_large_message_str);
4172*6dbdd20aSAndroid Build Coastguard Worker         packet->Finalize();
4173*6dbdd20aSAndroid Build Coastguard Worker       });
4174*6dbdd20aSAndroid Build Coastguard Worker 
4175*6dbdd20aSAndroid Build Coastguard Worker   // Simulate the start of a batching cycle by first setting the batching period
4176*6dbdd20aSAndroid Build Coastguard Worker   // to a very large value and then force-flushing when we are done writing
4177*6dbdd20aSAndroid Build Coastguard Worker   // data.
4178*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(
4179*6dbdd20aSAndroid Build Coastguard Worker       perfetto::test::EnableDirectSMBPatching(/*BackendType=*/GetParam()));
4180*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SetBatchCommitsDuration(UINT32_MAX,
4181*6dbdd20aSAndroid Build Coastguard Worker                                           /*BackendType=*/GetParam());
4182*6dbdd20aSAndroid Build Coastguard Worker 
4183*6dbdd20aSAndroid Build Coastguard Worker   std::stringstream second_large_message;
4184*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < 512; i++)
4185*6dbdd20aSAndroid Build Coastguard Worker     second_large_message << i << ". Something else wicked this way comes. ";
4186*6dbdd20aSAndroid Build Coastguard Worker   auto second_large_message_str = second_large_message.str();
4187*6dbdd20aSAndroid Build Coastguard Worker 
4188*6dbdd20aSAndroid Build Coastguard Worker   // Emit another trace event.
4189*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace(
4190*6dbdd20aSAndroid Build Coastguard Worker       [&second_large_message_str](MockDataSource::TraceContext ctx) {
4191*6dbdd20aSAndroid Build Coastguard Worker         auto packet = ctx.NewTracePacket();
4192*6dbdd20aSAndroid Build Coastguard Worker         packet->set_timestamp(43);
4193*6dbdd20aSAndroid Build Coastguard Worker         packet->set_for_testing()->set_str(second_large_message_str);
4194*6dbdd20aSAndroid Build Coastguard Worker         packet->Finalize();
4195*6dbdd20aSAndroid Build Coastguard Worker 
4196*6dbdd20aSAndroid Build Coastguard Worker         // Simulate the end of the batching cycle.
4197*6dbdd20aSAndroid Build Coastguard Worker         ctx.Flush();
4198*6dbdd20aSAndroid Build Coastguard Worker       });
4199*6dbdd20aSAndroid Build Coastguard Worker 
4200*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop.Wait();
4201*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->on_stop.Wait();
4202*6dbdd20aSAndroid Build Coastguard Worker 
4203*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
4204*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_GE(raw_trace.size(), 0u);
4205*6dbdd20aSAndroid Build Coastguard Worker 
4206*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace trace;
4207*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
4208*6dbdd20aSAndroid Build Coastguard Worker   bool test_packet_1_found = false;
4209*6dbdd20aSAndroid Build Coastguard Worker   bool test_packet_2_found = false;
4210*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
4211*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_for_testing())
4212*6dbdd20aSAndroid Build Coastguard Worker       continue;
4213*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(packet.timestamp() == 42U || packet.timestamp() == 43U);
4214*6dbdd20aSAndroid Build Coastguard Worker     if (packet.timestamp() == 42U) {
4215*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(test_packet_1_found);
4216*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(packet.for_testing().str(), first_large_message_str);
4217*6dbdd20aSAndroid Build Coastguard Worker       test_packet_1_found = true;
4218*6dbdd20aSAndroid Build Coastguard Worker     } else {
4219*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(test_packet_2_found);
4220*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(packet.for_testing().str(), second_large_message_str);
4221*6dbdd20aSAndroid Build Coastguard Worker       test_packet_2_found = true;
4222*6dbdd20aSAndroid Build Coastguard Worker     }
4223*6dbdd20aSAndroid Build Coastguard Worker   }
4224*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(test_packet_1_found && test_packet_2_found);
4225*6dbdd20aSAndroid Build Coastguard Worker }
4226*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,BlockingStartAndStop)4227*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, BlockingStartAndStop) {
4228*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
4229*6dbdd20aSAndroid Build Coastguard Worker 
4230*6dbdd20aSAndroid Build Coastguard Worker   // Register a second data source to get a bit more coverage.
4231*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceDescriptor dsd;
4232*6dbdd20aSAndroid Build Coastguard Worker   dsd.set_name("my_data_source2");
4233*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource2::Register(dsd, kTestDataSourceArg);
4234*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
4235*6dbdd20aSAndroid Build Coastguard Worker 
4236*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
4237*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4238*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
4239*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4240*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4241*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4242*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg = cfg.add_data_sources()->mutable_config();
4243*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source2");
4244*6dbdd20aSAndroid Build Coastguard Worker 
4245*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4246*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4247*6dbdd20aSAndroid Build Coastguard Worker 
4248*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4249*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(data_source->on_setup.notified());
4250*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(data_source->on_start.notified());
4251*6dbdd20aSAndroid Build Coastguard Worker 
4252*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4253*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(data_source->on_stop.notified());
4254*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(tracing_session->on_stop.notified());
4255*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::TracingMuxerImplInternalsForTest::
4256*6dbdd20aSAndroid Build Coastguard Worker       ClearDataSourceTlsStateOnReset<MockDataSource2>();
4257*6dbdd20aSAndroid Build Coastguard Worker }
4258*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,BlockingStartAndStopOnEmptySession)4259*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, BlockingStartAndStopOnEmptySession) {
4260*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
4261*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4262*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
4263*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4264*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4265*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("non_existent_data_source");
4266*6dbdd20aSAndroid Build Coastguard Worker 
4267*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4268*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4269*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4270*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4271*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(tracing_session->on_stop.notified());
4272*6dbdd20aSAndroid Build Coastguard Worker }
4273*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,WriteEventsAfterDeferredStop)4274*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, WriteEventsAfterDeferredStop) {
4275*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
4276*6dbdd20aSAndroid Build Coastguard Worker   data_source->handle_stop_asynchronously = true;
4277*6dbdd20aSAndroid Build Coastguard Worker 
4278*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config and start the tracing session.
4279*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4280*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
4281*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4282*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4283*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4284*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4285*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4286*6dbdd20aSAndroid Build Coastguard Worker 
4287*6dbdd20aSAndroid Build Coastguard Worker   // Stop and wait for the producer to have seen the stop event.
4288*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent consumer_stop_signal;
4289*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->SetOnStopCallback(
4290*6dbdd20aSAndroid Build Coastguard Worker       [&consumer_stop_signal] { consumer_stop_signal.Notify(); });
4291*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->Stop();
4292*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop.Wait();
4293*6dbdd20aSAndroid Build Coastguard Worker 
4294*6dbdd20aSAndroid Build Coastguard Worker   // At this point tracing should be still allowed because of the
4295*6dbdd20aSAndroid Build Coastguard Worker   // HandleStopAsynchronously() call.
4296*6dbdd20aSAndroid Build Coastguard Worker   bool lambda_called = false;
4297*6dbdd20aSAndroid Build Coastguard Worker 
4298*6dbdd20aSAndroid Build Coastguard Worker   // This usleep is here just to prevent that we accidentally pass the test
4299*6dbdd20aSAndroid Build Coastguard Worker   // just by virtue of hitting some race. We should be able to trace up until
4300*6dbdd20aSAndroid Build Coastguard Worker   // 5 seconds after seeing the stop when using the deferred stop mechanism.
4301*6dbdd20aSAndroid Build Coastguard Worker   std::this_thread::sleep_for(std::chrono::milliseconds(250));
4302*6dbdd20aSAndroid Build Coastguard Worker 
4303*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace([&lambda_called](MockDataSource::TraceContext ctx) {
4304*6dbdd20aSAndroid Build Coastguard Worker     auto packet = ctx.NewTracePacket();
4305*6dbdd20aSAndroid Build Coastguard Worker     packet->set_for_testing()->set_str("event written after OnStop");
4306*6dbdd20aSAndroid Build Coastguard Worker     packet->Finalize();
4307*6dbdd20aSAndroid Build Coastguard Worker     ctx.Flush();
4308*6dbdd20aSAndroid Build Coastguard Worker     lambda_called = true;
4309*6dbdd20aSAndroid Build Coastguard Worker   });
4310*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(lambda_called);
4311*6dbdd20aSAndroid Build Coastguard Worker 
4312*6dbdd20aSAndroid Build Coastguard Worker   // Now call the async stop closure. This acks the stop to the service and
4313*6dbdd20aSAndroid Build Coastguard Worker   // disallows further Trace() calls.
4314*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(data_source->async_stop_closure);
4315*6dbdd20aSAndroid Build Coastguard Worker   data_source->async_stop_closure();
4316*6dbdd20aSAndroid Build Coastguard Worker 
4317*6dbdd20aSAndroid Build Coastguard Worker   // Wait that the stop is propagated to the consumer.
4318*6dbdd20aSAndroid Build Coastguard Worker   consumer_stop_signal.Wait();
4319*6dbdd20aSAndroid Build Coastguard Worker 
4320*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace([](MockDataSource::TraceContext) {
4321*6dbdd20aSAndroid Build Coastguard Worker     FAIL() << "Should not be called after the stop is acked";
4322*6dbdd20aSAndroid Build Coastguard Worker   });
4323*6dbdd20aSAndroid Build Coastguard Worker 
4324*6dbdd20aSAndroid Build Coastguard Worker   // Check the contents of the trace.
4325*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
4326*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_GE(raw_trace.size(), 0u);
4327*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace trace;
4328*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
4329*6dbdd20aSAndroid Build Coastguard Worker   int test_packet_found = 0;
4330*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
4331*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_for_testing())
4332*6dbdd20aSAndroid Build Coastguard Worker       continue;
4333*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(packet.for_testing().str(), "event written after OnStop");
4334*6dbdd20aSAndroid Build Coastguard Worker     test_packet_found++;
4335*6dbdd20aSAndroid Build Coastguard Worker   }
4336*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(test_packet_found, 1);
4337*6dbdd20aSAndroid Build Coastguard Worker }
4338*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,RepeatedStartAndStop)4339*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, RepeatedStartAndStop) {
4340*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4341*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
4342*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4343*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4344*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4345*6dbdd20aSAndroid Build Coastguard Worker 
4346*6dbdd20aSAndroid Build Coastguard Worker   for (int i = 0; i < 5; i++) {
4347*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTrace(cfg);
4348*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->Start();
4349*6dbdd20aSAndroid Build Coastguard Worker     std::atomic<bool> stop_called{false};
4350*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->SetOnStopCallback(
4351*6dbdd20aSAndroid Build Coastguard Worker         [&stop_called] { stop_called = true; });
4352*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StopBlocking();
4353*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(stop_called);
4354*6dbdd20aSAndroid Build Coastguard Worker   }
4355*6dbdd20aSAndroid Build Coastguard Worker }
4356*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,SetupWithFile)4357*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, SetupWithFile) {
4358*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4359*6dbdd20aSAndroid Build Coastguard Worker   if (GetParam() == perfetto::kSystemBackend)
4360*6dbdd20aSAndroid Build Coastguard Worker     GTEST_SKIP() << "write_into_file + system mode is not supported on Windows";
4361*6dbdd20aSAndroid Build Coastguard Worker #endif
4362*6dbdd20aSAndroid Build Coastguard Worker   auto temp_file = perfetto::test::CreateTempFile();
4363*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4364*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
4365*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4366*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4367*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4368*6dbdd20aSAndroid Build Coastguard Worker   // Write a trace into |fd|.
4369*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg, temp_file.fd);
4370*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4371*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4372*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4373*6dbdd20aSAndroid Build Coastguard Worker   // Check that |fd| didn't get closed.
4374*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(0, fcntl(temp_file.fd, F_GETFD, 0));
4375*6dbdd20aSAndroid Build Coastguard Worker #endif
4376*6dbdd20aSAndroid Build Coastguard Worker   // Check that the trace got written.
4377*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_GT(lseek(temp_file.fd, 0, SEEK_END), 0);
4378*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(0, close(temp_file.fd));
4379*6dbdd20aSAndroid Build Coastguard Worker   // Clean up.
4380*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(0, remove(temp_file.path.c_str()));
4381*6dbdd20aSAndroid Build Coastguard Worker }
4382*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,MultipleRegistrations)4383*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, MultipleRegistrations) {
4384*6dbdd20aSAndroid Build Coastguard Worker   // Attempt to register the same data source again.
4385*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceDescriptor dsd;
4386*6dbdd20aSAndroid Build Coastguard Worker   dsd.set_name("my_data_source");
4387*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(MockDataSource::Register(dsd));
4388*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
4389*6dbdd20aSAndroid Build Coastguard Worker 
4390*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
4391*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4392*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
4393*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4394*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4395*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4396*6dbdd20aSAndroid Build Coastguard Worker 
4397*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4398*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4399*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4400*6dbdd20aSAndroid Build Coastguard Worker 
4401*6dbdd20aSAndroid Build Coastguard Worker   // Emit one trace event.
4402*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<int> trace_lambda_calls{0};
4403*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace([&trace_lambda_calls](MockDataSource::TraceContext) {
4404*6dbdd20aSAndroid Build Coastguard Worker     trace_lambda_calls++;
4405*6dbdd20aSAndroid Build Coastguard Worker   });
4406*6dbdd20aSAndroid Build Coastguard Worker 
4407*6dbdd20aSAndroid Build Coastguard Worker   // Make sure the data source got called only once.
4408*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4409*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(trace_lambda_calls, 1);
4410*6dbdd20aSAndroid Build Coastguard Worker }
4411*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,CustomIncrementalState)4412*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, CustomIncrementalState) {
4413*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceDescriptor dsd;
4414*6dbdd20aSAndroid Build Coastguard Worker   dsd.set_name("incr_data_source");
4415*6dbdd20aSAndroid Build Coastguard Worker   TestIncrementalDataSource::Register(dsd);
4416*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
4417*6dbdd20aSAndroid Build Coastguard Worker 
4418*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
4419*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4420*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
4421*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4422*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4423*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("incr_data_source");
4424*6dbdd20aSAndroid Build Coastguard Worker 
4425*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4426*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4427*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4428*6dbdd20aSAndroid Build Coastguard Worker 
4429*6dbdd20aSAndroid Build Coastguard Worker   // First emit a no-op trace event that initializes the incremental state as a
4430*6dbdd20aSAndroid Build Coastguard Worker   // side effect.
4431*6dbdd20aSAndroid Build Coastguard Worker   TestIncrementalDataSource::Trace(
4432*6dbdd20aSAndroid Build Coastguard Worker       [](TestIncrementalDataSource::TraceContext) {});
4433*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(TestIncrementalState::constructed);
4434*6dbdd20aSAndroid Build Coastguard Worker 
4435*6dbdd20aSAndroid Build Coastguard Worker   // Check that the incremental state is carried across trace events.
4436*6dbdd20aSAndroid Build Coastguard Worker   TestIncrementalDataSource::Trace(
4437*6dbdd20aSAndroid Build Coastguard Worker       [](TestIncrementalDataSource::TraceContext ctx) {
4438*6dbdd20aSAndroid Build Coastguard Worker         auto* state = ctx.GetIncrementalState();
4439*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(state);
4440*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(100, state->count);
4441*6dbdd20aSAndroid Build Coastguard Worker         state->count++;
4442*6dbdd20aSAndroid Build Coastguard Worker       });
4443*6dbdd20aSAndroid Build Coastguard Worker 
4444*6dbdd20aSAndroid Build Coastguard Worker   TestIncrementalDataSource::Trace(
4445*6dbdd20aSAndroid Build Coastguard Worker       [](TestIncrementalDataSource::TraceContext ctx) {
4446*6dbdd20aSAndroid Build Coastguard Worker         auto* state = ctx.GetIncrementalState();
4447*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(101, state->count);
4448*6dbdd20aSAndroid Build Coastguard Worker       });
4449*6dbdd20aSAndroid Build Coastguard Worker 
4450*6dbdd20aSAndroid Build Coastguard Worker   // Make sure the incremental state gets cleaned up between sessions.
4451*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4452*6dbdd20aSAndroid Build Coastguard Worker   tracing_session = NewTrace(cfg);
4453*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4454*6dbdd20aSAndroid Build Coastguard Worker   TestIncrementalDataSource::Trace(
4455*6dbdd20aSAndroid Build Coastguard Worker       [](TestIncrementalDataSource::TraceContext ctx) {
4456*6dbdd20aSAndroid Build Coastguard Worker         auto* state = ctx.GetIncrementalState();
4457*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(TestIncrementalState::destroyed);
4458*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(state);
4459*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(100, state->count);
4460*6dbdd20aSAndroid Build Coastguard Worker       });
4461*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4462*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::TracingMuxerImplInternalsForTest::
4463*6dbdd20aSAndroid Build Coastguard Worker       ClearDataSourceTlsStateOnReset<TestIncrementalDataSource>();
4464*6dbdd20aSAndroid Build Coastguard Worker }
4465*6dbdd20aSAndroid Build Coastguard Worker 
4466*6dbdd20aSAndroid Build Coastguard Worker const void* const kKey1 = &kKey1;
4467*6dbdd20aSAndroid Build Coastguard Worker const void* const kKey2 = &kKey2;
4468*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventUserData)4469*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventUserData) {
4470*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4471*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
4472*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4473*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEventTlsStateUserData* data_1_ptr = nullptr;
4474*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEventTlsStateUserData* data_2_ptr = nullptr;
4475*6dbdd20aSAndroid Build Coastguard Worker 
4476*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN(
4477*6dbdd20aSAndroid Build Coastguard Worker       "foo", "E", [&data_1_ptr, &data_2_ptr](perfetto::EventContext& ctx) {
4478*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, ctx.GetTlsUserData(kKey1));
4479*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(nullptr, ctx.GetTlsUserData(kKey2));
4480*6dbdd20aSAndroid Build Coastguard Worker         std::unique_ptr<perfetto::TrackEventTlsStateUserData> data_1 =
4481*6dbdd20aSAndroid Build Coastguard Worker             std::make_unique<perfetto::TrackEventTlsStateUserData>();
4482*6dbdd20aSAndroid Build Coastguard Worker         data_1_ptr = data_1.get();
4483*6dbdd20aSAndroid Build Coastguard Worker         std::unique_ptr<perfetto::TrackEventTlsStateUserData> data_2 =
4484*6dbdd20aSAndroid Build Coastguard Worker             std::make_unique<perfetto::TrackEventTlsStateUserData>();
4485*6dbdd20aSAndroid Build Coastguard Worker         data_2_ptr = data_2.get();
4486*6dbdd20aSAndroid Build Coastguard Worker         ctx.SetTlsUserData(kKey1, std::move(data_1));
4487*6dbdd20aSAndroid Build Coastguard Worker         ctx.SetTlsUserData(kKey2, std::move(data_2));
4488*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(data_1_ptr, ctx.GetTlsUserData(kKey1));
4489*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(data_2_ptr, ctx.GetTlsUserData(kKey2));
4490*6dbdd20aSAndroid Build Coastguard Worker       });
4491*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
4492*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "F",
4493*6dbdd20aSAndroid Build Coastguard Worker                     [&data_1_ptr, &data_2_ptr](perfetto::EventContext& ctx) {
4494*6dbdd20aSAndroid Build Coastguard Worker                       EXPECT_EQ(data_1_ptr, ctx.GetTlsUserData(kKey1));
4495*6dbdd20aSAndroid Build Coastguard Worker                       EXPECT_EQ(data_2_ptr, ctx.GetTlsUserData(kKey2));
4496*6dbdd20aSAndroid Build Coastguard Worker                     });
4497*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
4498*6dbdd20aSAndroid Build Coastguard Worker 
4499*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
4500*6dbdd20aSAndroid Build Coastguard Worker 
4501*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(ReadSlicesFromTrace(raw_trace),
4502*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:foo.E", "E", "B:foo.F", "E"));
4503*6dbdd20aSAndroid Build Coastguard Worker 
4504*6dbdd20aSAndroid Build Coastguard Worker   // Expect that the TLS User Data is cleared between tracing sessions.
4505*6dbdd20aSAndroid Build Coastguard Worker   tracing_session = NewTraceWithCategories({"foo"});
4506*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4507*6dbdd20aSAndroid Build Coastguard Worker 
4508*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "E", [](perfetto::EventContext& ctx) {
4509*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(nullptr, ctx.GetTlsUserData(kKey1));
4510*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(nullptr, ctx.GetTlsUserData(kKey2));
4511*6dbdd20aSAndroid Build Coastguard Worker   });
4512*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
4513*6dbdd20aSAndroid Build Coastguard Worker 
4514*6dbdd20aSAndroid Build Coastguard Worker   raw_trace = StopSessionAndReturnBytes(tracing_session);
4515*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(ReadSlicesFromTrace(raw_trace), ElementsAre("B:foo.E", "E"));
4516*6dbdd20aSAndroid Build Coastguard Worker }
4517*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,OnFlush)4518*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, OnFlush) {
4519*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
4520*6dbdd20aSAndroid Build Coastguard Worker 
4521*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
4522*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4523*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4524*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4525*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4526*6dbdd20aSAndroid Build Coastguard Worker 
4527*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4528*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4529*6dbdd20aSAndroid Build Coastguard Worker 
4530*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4531*6dbdd20aSAndroid Build Coastguard Worker 
4532*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent producer_on_flush;
4533*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent consumer_flush_done;
4534*6dbdd20aSAndroid Build Coastguard Worker 
4535*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_flush_callback = [&](perfetto::FlushFlags flush_flags) {
4536*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(consumer_flush_done.notified());
4537*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(flush_flags.initiator(),
4538*6dbdd20aSAndroid Build Coastguard Worker               perfetto::FlushFlags::Initiator::kConsumerSdk);
4539*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(flush_flags.reason(), perfetto::FlushFlags::Reason::kExplicit);
4540*6dbdd20aSAndroid Build Coastguard Worker     producer_on_flush.Notify();
4541*6dbdd20aSAndroid Build Coastguard Worker     MockDataSource::Trace([](MockDataSource::TraceContext ctx) {
4542*6dbdd20aSAndroid Build Coastguard Worker       ctx.NewTracePacket()->set_for_testing()->set_str("on-flush");
4543*6dbdd20aSAndroid Build Coastguard Worker       ctx.Flush();
4544*6dbdd20aSAndroid Build Coastguard Worker     });
4545*6dbdd20aSAndroid Build Coastguard Worker   };
4546*6dbdd20aSAndroid Build Coastguard Worker 
4547*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->Flush([&](bool success) {
4548*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(success);
4549*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(producer_on_flush.notified());
4550*6dbdd20aSAndroid Build Coastguard Worker     consumer_flush_done.Notify();
4551*6dbdd20aSAndroid Build Coastguard Worker   });
4552*6dbdd20aSAndroid Build Coastguard Worker 
4553*6dbdd20aSAndroid Build Coastguard Worker   producer_on_flush.Wait();
4554*6dbdd20aSAndroid Build Coastguard Worker   consumer_flush_done.Wait();
4555*6dbdd20aSAndroid Build Coastguard Worker 
4556*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4557*6dbdd20aSAndroid Build Coastguard Worker 
4558*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop.Wait();
4559*6dbdd20aSAndroid Build Coastguard Worker 
4560*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
4561*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_GE(raw_trace.size(), 0u);
4562*6dbdd20aSAndroid Build Coastguard Worker 
4563*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace trace;
4564*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
4565*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
4566*6dbdd20aSAndroid Build Coastguard Worker       trace.packet(),
4567*6dbdd20aSAndroid Build Coastguard Worker       Contains(Property(
4568*6dbdd20aSAndroid Build Coastguard Worker           &perfetto::protos::gen::TracePacket::for_testing,
4569*6dbdd20aSAndroid Build Coastguard Worker           Property(&perfetto::protos::gen::TestEvent::str, "on-flush"))));
4570*6dbdd20aSAndroid Build Coastguard Worker }
4571*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,OnFlushAsync)4572*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, OnFlushAsync) {
4573*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
4574*6dbdd20aSAndroid Build Coastguard Worker 
4575*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
4576*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4577*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4578*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4579*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4580*6dbdd20aSAndroid Build Coastguard Worker 
4581*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4582*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4583*6dbdd20aSAndroid Build Coastguard Worker 
4584*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4585*6dbdd20aSAndroid Build Coastguard Worker 
4586*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent consumer_flush_done;
4587*6dbdd20aSAndroid Build Coastguard Worker 
4588*6dbdd20aSAndroid Build Coastguard Worker   data_source->handle_flush_asynchronously = true;
4589*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_flush_callback = [&](perfetto::FlushFlags) {
4590*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(consumer_flush_done.notified());
4591*6dbdd20aSAndroid Build Coastguard Worker   };
4592*6dbdd20aSAndroid Build Coastguard Worker 
4593*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->Flush([&](bool success) {
4594*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(success);
4595*6dbdd20aSAndroid Build Coastguard Worker     consumer_flush_done.Notify();
4596*6dbdd20aSAndroid Build Coastguard Worker   });
4597*6dbdd20aSAndroid Build Coastguard Worker 
4598*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_flush.Wait();
4599*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
4600*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(consumer_flush_done.notified());
4601*6dbdd20aSAndroid Build Coastguard Worker 
4602*6dbdd20aSAndroid Build Coastguard Worker   // Finish the flush asynchronously
4603*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace([](MockDataSource::TraceContext ctx) {
4604*6dbdd20aSAndroid Build Coastguard Worker     ctx.NewTracePacket()->set_for_testing()->set_str("on-flush");
4605*6dbdd20aSAndroid Build Coastguard Worker     ctx.Flush();
4606*6dbdd20aSAndroid Build Coastguard Worker   });
4607*6dbdd20aSAndroid Build Coastguard Worker   data_source->async_flush_closure();
4608*6dbdd20aSAndroid Build Coastguard Worker 
4609*6dbdd20aSAndroid Build Coastguard Worker   consumer_flush_done.Wait();
4610*6dbdd20aSAndroid Build Coastguard Worker 
4611*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4612*6dbdd20aSAndroid Build Coastguard Worker 
4613*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop.Wait();
4614*6dbdd20aSAndroid Build Coastguard Worker 
4615*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
4616*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_GE(raw_trace.size(), 0u);
4617*6dbdd20aSAndroid Build Coastguard Worker 
4618*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace trace;
4619*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
4620*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
4621*6dbdd20aSAndroid Build Coastguard Worker       trace.packet(),
4622*6dbdd20aSAndroid Build Coastguard Worker       Contains(Property(
4623*6dbdd20aSAndroid Build Coastguard Worker           &perfetto::protos::gen::TracePacket::for_testing,
4624*6dbdd20aSAndroid Build Coastguard Worker           Property(&perfetto::protos::gen::TestEvent::str, "on-flush"))));
4625*6dbdd20aSAndroid Build Coastguard Worker }
4626*6dbdd20aSAndroid Build Coastguard Worker 
4627*6dbdd20aSAndroid Build Coastguard Worker // Regression test for b/139110180. Checks that GetDataSourceLocked() can be
4628*6dbdd20aSAndroid Build Coastguard Worker // called from OnStart() and OnStop() callbacks without deadlocking.
TEST_P(PerfettoApiTest,GetDataSourceLockedFromCallbacks)4629*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, GetDataSourceLockedFromCallbacks) {
4630*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
4631*6dbdd20aSAndroid Build Coastguard Worker 
4632*6dbdd20aSAndroid Build Coastguard Worker   // Setup the trace config.
4633*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4634*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(1);
4635*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4636*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4637*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
4638*6dbdd20aSAndroid Build Coastguard Worker 
4639*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
4640*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4641*6dbdd20aSAndroid Build Coastguard Worker 
4642*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_start_callback = [] {
4643*6dbdd20aSAndroid Build Coastguard Worker     MockDataSource::Trace([](MockDataSource::TraceContext ctx) {
4644*6dbdd20aSAndroid Build Coastguard Worker       ctx.NewTracePacket()->set_for_testing()->set_str("on-start");
4645*6dbdd20aSAndroid Build Coastguard Worker       auto ds = ctx.GetDataSourceLocked();
4646*6dbdd20aSAndroid Build Coastguard Worker       ASSERT_TRUE(!!ds);
4647*6dbdd20aSAndroid Build Coastguard Worker       ctx.NewTracePacket()->set_for_testing()->set_str("on-start-locked");
4648*6dbdd20aSAndroid Build Coastguard Worker     });
4649*6dbdd20aSAndroid Build Coastguard Worker   };
4650*6dbdd20aSAndroid Build Coastguard Worker 
4651*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop_callback = [] {
4652*6dbdd20aSAndroid Build Coastguard Worker     MockDataSource::Trace([](MockDataSource::TraceContext ctx) {
4653*6dbdd20aSAndroid Build Coastguard Worker       ctx.NewTracePacket()->set_for_testing()->set_str("on-stop");
4654*6dbdd20aSAndroid Build Coastguard Worker       auto ds = ctx.GetDataSourceLocked();
4655*6dbdd20aSAndroid Build Coastguard Worker       ASSERT_TRUE(!!ds);
4656*6dbdd20aSAndroid Build Coastguard Worker       ctx.NewTracePacket()->set_for_testing()->set_str("on-stop-locked");
4657*6dbdd20aSAndroid Build Coastguard Worker       ctx.Flush();
4658*6dbdd20aSAndroid Build Coastguard Worker     });
4659*6dbdd20aSAndroid Build Coastguard Worker   };
4660*6dbdd20aSAndroid Build Coastguard Worker 
4661*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->Start();
4662*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop.Wait();
4663*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->on_stop.Wait();
4664*6dbdd20aSAndroid Build Coastguard Worker 
4665*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> raw_trace = tracing_session->get()->ReadTraceBlocking();
4666*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_GE(raw_trace.size(), 0u);
4667*6dbdd20aSAndroid Build Coastguard Worker 
4668*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace trace;
4669*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
4670*6dbdd20aSAndroid Build Coastguard Worker   int packets_found = 0;
4671*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
4672*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_for_testing())
4673*6dbdd20aSAndroid Build Coastguard Worker       continue;
4674*6dbdd20aSAndroid Build Coastguard Worker     packets_found |= packet.for_testing().str() == "on-start" ? 1 : 0;
4675*6dbdd20aSAndroid Build Coastguard Worker     packets_found |= packet.for_testing().str() == "on-start-locked" ? 2 : 0;
4676*6dbdd20aSAndroid Build Coastguard Worker     packets_found |= packet.for_testing().str() == "on-stop" ? 4 : 0;
4677*6dbdd20aSAndroid Build Coastguard Worker     packets_found |= packet.for_testing().str() == "on-stop-locked" ? 8 : 0;
4678*6dbdd20aSAndroid Build Coastguard Worker   }
4679*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(packets_found, 1 | 2 | 4 | 8);
4680*6dbdd20aSAndroid Build Coastguard Worker }
4681*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,OnStartCallback)4682*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, OnStartCallback) {
4683*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4684*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(60000);
4685*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4686*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4687*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
4688*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4689*6dbdd20aSAndroid Build Coastguard Worker 
4690*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent got_start;
4691*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->SetOnStartCallback([&] { got_start.Notify(); });
4692*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->Start();
4693*6dbdd20aSAndroid Build Coastguard Worker   got_start.Wait();
4694*6dbdd20aSAndroid Build Coastguard Worker 
4695*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4696*6dbdd20aSAndroid Build Coastguard Worker }
4697*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,OnErrorCallback)4698*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, OnErrorCallback) {
4699*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4700*6dbdd20aSAndroid Build Coastguard Worker 
4701*6dbdd20aSAndroid Build Coastguard Worker   // Requesting too long |duration_ms| will cause EnableTracing() to fail.
4702*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(static_cast<uint32_t>(-1));
4703*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4704*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4705*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
4706*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4707*6dbdd20aSAndroid Build Coastguard Worker 
4708*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent got_error;
4709*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->SetOnErrorCallback([&](perfetto::TracingError error) {
4710*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(perfetto::TracingError::kTracingFailed, error.code);
4711*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(error.message.empty());
4712*6dbdd20aSAndroid Build Coastguard Worker     got_error.Notify();
4713*6dbdd20aSAndroid Build Coastguard Worker   });
4714*6dbdd20aSAndroid Build Coastguard Worker 
4715*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->Start();
4716*6dbdd20aSAndroid Build Coastguard Worker   got_error.Wait();
4717*6dbdd20aSAndroid Build Coastguard Worker 
4718*6dbdd20aSAndroid Build Coastguard Worker   // Registered error callback will be triggered also by OnDisconnect()
4719*6dbdd20aSAndroid Build Coastguard Worker   // function. This may happen after exiting this test what would result in
4720*6dbdd20aSAndroid Build Coastguard Worker   // system crash (|got_error| will not exist at that time). To prevent that
4721*6dbdd20aSAndroid Build Coastguard Worker   // scenario, error callback has to be cleared.
4722*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->SetOnErrorCallback(nullptr);
4723*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4724*6dbdd20aSAndroid Build Coastguard Worker }
4725*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,UnsupportedBackend)4726*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, UnsupportedBackend) {
4727*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session with an invalid backend type specified.
4728*6dbdd20aSAndroid Build Coastguard Worker   // Specifically, the custom backend isn't initialized for these tests.
4729*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4730*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4731*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg, perfetto::BackendType::kCustomBackend);
4732*6dbdd20aSAndroid Build Coastguard Worker 
4733*6dbdd20aSAndroid Build Coastguard Worker   // Creating the consumer should cause an asynchronous disconnect error.
4734*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent got_error;
4735*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->SetOnErrorCallback([&](perfetto::TracingError error) {
4736*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(perfetto::TracingError::kDisconnected, error.code);
4737*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(error.message.empty());
4738*6dbdd20aSAndroid Build Coastguard Worker     got_error.Notify();
4739*6dbdd20aSAndroid Build Coastguard Worker   });
4740*6dbdd20aSAndroid Build Coastguard Worker   got_error.Wait();
4741*6dbdd20aSAndroid Build Coastguard Worker 
4742*6dbdd20aSAndroid Build Coastguard Worker   // Clear the callback for test tear down.
4743*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->SetOnErrorCallback(nullptr);
4744*6dbdd20aSAndroid Build Coastguard Worker   // Synchronize the consumer channel to ensure the callback has propagated.
4745*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4746*6dbdd20aSAndroid Build Coastguard Worker }
4747*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ForbiddenConsumer)4748*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ForbiddenConsumer) {
4749*6dbdd20aSAndroid Build Coastguard Worker   g_test_tracing_policy->should_allow_consumer_connection = false;
4750*6dbdd20aSAndroid Build Coastguard Worker 
4751*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session while consumer connections are forbidden.
4752*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4753*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4754*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4755*6dbdd20aSAndroid Build Coastguard Worker 
4756*6dbdd20aSAndroid Build Coastguard Worker   // Creating the consumer should cause an asynchronous disconnect error.
4757*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent got_error;
4758*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->SetOnErrorCallback([&](perfetto::TracingError error) {
4759*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(perfetto::TracingError::kDisconnected, error.code);
4760*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(error.message.empty());
4761*6dbdd20aSAndroid Build Coastguard Worker     got_error.Notify();
4762*6dbdd20aSAndroid Build Coastguard Worker   });
4763*6dbdd20aSAndroid Build Coastguard Worker   got_error.Wait();
4764*6dbdd20aSAndroid Build Coastguard Worker 
4765*6dbdd20aSAndroid Build Coastguard Worker   // Clear the callback for test tear down.
4766*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->SetOnErrorCallback(nullptr);
4767*6dbdd20aSAndroid Build Coastguard Worker   // Synchronize the consumer channel to ensure the callback has propagated.
4768*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4769*6dbdd20aSAndroid Build Coastguard Worker 
4770*6dbdd20aSAndroid Build Coastguard Worker   g_test_tracing_policy->should_allow_consumer_connection = true;
4771*6dbdd20aSAndroid Build Coastguard Worker }
4772*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,GetTraceStats)4773*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, GetTraceStats) {
4774*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4775*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
4776*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4777*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4778*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
4779*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4780*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4781*6dbdd20aSAndroid Build Coastguard Worker 
4782*6dbdd20aSAndroid Build Coastguard Worker   // Asynchronous read.
4783*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent got_stats;
4784*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->GetTraceStats(
4785*6dbdd20aSAndroid Build Coastguard Worker       [&got_stats](perfetto::TracingSession::GetTraceStatsCallbackArgs args) {
4786*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::gen::TraceStats trace_stats;
4787*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(args.success);
4788*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(trace_stats.ParseFromArray(args.trace_stats_data.data(),
4789*6dbdd20aSAndroid Build Coastguard Worker                                                args.trace_stats_data.size()));
4790*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(1, trace_stats.buffer_stats_size());
4791*6dbdd20aSAndroid Build Coastguard Worker         got_stats.Notify();
4792*6dbdd20aSAndroid Build Coastguard Worker       });
4793*6dbdd20aSAndroid Build Coastguard Worker   got_stats.Wait();
4794*6dbdd20aSAndroid Build Coastguard Worker 
4795*6dbdd20aSAndroid Build Coastguard Worker   // Blocking read.
4796*6dbdd20aSAndroid Build Coastguard Worker   auto stats = tracing_session->get()->GetTraceStatsBlocking();
4797*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TraceStats trace_stats;
4798*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(stats.success);
4799*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(trace_stats.ParseFromArray(stats.trace_stats_data.data(),
4800*6dbdd20aSAndroid Build Coastguard Worker                                          stats.trace_stats_data.size()));
4801*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(1, trace_stats.buffer_stats_size());
4802*6dbdd20aSAndroid Build Coastguard Worker 
4803*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4804*6dbdd20aSAndroid Build Coastguard Worker }
4805*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,CustomDataSource)4806*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, CustomDataSource) {
4807*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
4808*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
4809*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
4810*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("CustomDataSource");
4811*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
4812*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
4813*6dbdd20aSAndroid Build Coastguard Worker   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
4814*6dbdd20aSAndroid Build Coastguard Worker     auto packet = ctx.NewTracePacket();
4815*6dbdd20aSAndroid Build Coastguard Worker     packet->set_timestamp(4200000);
4816*6dbdd20aSAndroid Build Coastguard Worker     packet->set_for_testing()->set_str("Test String");
4817*6dbdd20aSAndroid Build Coastguard Worker   });
4818*6dbdd20aSAndroid Build Coastguard Worker   CustomDataSource::Trace(
4819*6dbdd20aSAndroid Build Coastguard Worker       [](CustomDataSource::TraceContext ctx) { ctx.Flush(); });
4820*6dbdd20aSAndroid Build Coastguard Worker 
4821*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
4822*6dbdd20aSAndroid Build Coastguard Worker   auto bytes = tracing_session->get()->ReadTraceBlocking();
4823*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace parsed_trace;
4824*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(parsed_trace.ParseFromArray(bytes.data(), bytes.size()));
4825*6dbdd20aSAndroid Build Coastguard Worker   bool found_for_testing = false;
4826*6dbdd20aSAndroid Build Coastguard Worker   for (auto& packet : parsed_trace.packet()) {
4827*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_for_testing()) {
4828*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(found_for_testing);
4829*6dbdd20aSAndroid Build Coastguard Worker       found_for_testing = true;
4830*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(4200000u, packet.timestamp());
4831*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("Test String", packet.for_testing().str());
4832*6dbdd20aSAndroid Build Coastguard Worker     }
4833*6dbdd20aSAndroid Build Coastguard Worker   }
4834*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_for_testing);
4835*6dbdd20aSAndroid Build Coastguard Worker }
4836*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,QueryServiceState)4837*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, QueryServiceState) {
4838*6dbdd20aSAndroid Build Coastguard Worker   class QueryTestDataSource : public perfetto::DataSource<QueryTestDataSource> {
4839*6dbdd20aSAndroid Build Coastguard Worker   };
4840*6dbdd20aSAndroid Build Coastguard Worker   RegisterDataSource<QueryTestDataSource>("query_test_data_source");
4841*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
4842*6dbdd20aSAndroid Build Coastguard Worker 
4843*6dbdd20aSAndroid Build Coastguard Worker   auto tracing_session =
4844*6dbdd20aSAndroid Build Coastguard Worker       perfetto::Tracing::NewTrace(/*BackendType=*/GetParam());
4845*6dbdd20aSAndroid Build Coastguard Worker   // Asynchronous read.
4846*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent got_state;
4847*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->QueryServiceState(
4848*6dbdd20aSAndroid Build Coastguard Worker       [&got_state](
4849*6dbdd20aSAndroid Build Coastguard Worker           perfetto::TracingSession::QueryServiceStateCallbackArgs result) {
4850*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::gen::TracingServiceState state;
4851*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(result.success);
4852*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(state.ParseFromArray(result.service_state_data.data(),
4853*6dbdd20aSAndroid Build Coastguard Worker                                          result.service_state_data.size()));
4854*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(1, state.producers_size());
4855*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_NE(std::string::npos,
4856*6dbdd20aSAndroid Build Coastguard Worker                   state.producers()[0].name().find("integrationtest"));
4857*6dbdd20aSAndroid Build Coastguard Worker         bool found_ds = false;
4858*6dbdd20aSAndroid Build Coastguard Worker         for (const auto& ds : state.data_sources())
4859*6dbdd20aSAndroid Build Coastguard Worker           found_ds |= ds.ds_descriptor().name() == "query_test_data_source";
4860*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_TRUE(found_ds);
4861*6dbdd20aSAndroid Build Coastguard Worker         got_state.Notify();
4862*6dbdd20aSAndroid Build Coastguard Worker       });
4863*6dbdd20aSAndroid Build Coastguard Worker   got_state.Wait();
4864*6dbdd20aSAndroid Build Coastguard Worker 
4865*6dbdd20aSAndroid Build Coastguard Worker   // Blocking read.
4866*6dbdd20aSAndroid Build Coastguard Worker   auto result = tracing_session->QueryServiceStateBlocking();
4867*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TracingServiceState state;
4868*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(result.success);
4869*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(state.ParseFromArray(result.service_state_data.data(),
4870*6dbdd20aSAndroid Build Coastguard Worker                                    result.service_state_data.size()));
4871*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(1, state.producers_size());
4872*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos,
4873*6dbdd20aSAndroid Build Coastguard Worker             state.producers()[0].name().find("integrationtest"));
4874*6dbdd20aSAndroid Build Coastguard Worker   bool found_ds = false;
4875*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& ds : state.data_sources())
4876*6dbdd20aSAndroid Build Coastguard Worker     found_ds |= ds.ds_descriptor().name() == "query_test_data_source";
4877*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_ds);
4878*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::TracingMuxerImplInternalsForTest::
4879*6dbdd20aSAndroid Build Coastguard Worker       ClearDataSourceTlsStateOnReset<QueryTestDataSource>();
4880*6dbdd20aSAndroid Build Coastguard Worker }
4881*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,UpdateDataSource)4882*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, UpdateDataSource) {
4883*6dbdd20aSAndroid Build Coastguard Worker   class UpdateTestDataSource
4884*6dbdd20aSAndroid Build Coastguard Worker       : public perfetto::DataSource<UpdateTestDataSource> {};
4885*6dbdd20aSAndroid Build Coastguard Worker 
4886*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceDescriptor dsd;
4887*6dbdd20aSAndroid Build Coastguard Worker   dsd.set_name("update_test_data_source");
4888*6dbdd20aSAndroid Build Coastguard Worker 
4889*6dbdd20aSAndroid Build Coastguard Worker   RegisterDataSource<UpdateTestDataSource>(dsd);
4890*6dbdd20aSAndroid Build Coastguard Worker 
4891*6dbdd20aSAndroid Build Coastguard Worker   {
4892*6dbdd20aSAndroid Build Coastguard Worker     protozero::HeapBuffered<perfetto::protos::pbzero::TrackEventDescriptor> ted;
4893*6dbdd20aSAndroid Build Coastguard Worker     auto cat = ted->add_available_categories();
4894*6dbdd20aSAndroid Build Coastguard Worker     cat->set_name("new_cat");
4895*6dbdd20aSAndroid Build Coastguard Worker     dsd.set_track_event_descriptor_raw(ted.SerializeAsString());
4896*6dbdd20aSAndroid Build Coastguard Worker   }
4897*6dbdd20aSAndroid Build Coastguard Worker 
4898*6dbdd20aSAndroid Build Coastguard Worker   UpdateDataSource<UpdateTestDataSource>(dsd);
4899*6dbdd20aSAndroid Build Coastguard Worker 
4900*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
4901*6dbdd20aSAndroid Build Coastguard Worker 
4902*6dbdd20aSAndroid Build Coastguard Worker   auto tracing_session =
4903*6dbdd20aSAndroid Build Coastguard Worker       perfetto::Tracing::NewTrace(/*BackendType=*/GetParam());
4904*6dbdd20aSAndroid Build Coastguard Worker   // Blocking read.
4905*6dbdd20aSAndroid Build Coastguard Worker   auto result = tracing_session->QueryServiceStateBlocking();
4906*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TracingServiceState state;
4907*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(result.success);
4908*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(state.ParseFromArray(result.service_state_data.data(),
4909*6dbdd20aSAndroid Build Coastguard Worker                                    result.service_state_data.size()));
4910*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(1, state.producers_size());
4911*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(std::string::npos,
4912*6dbdd20aSAndroid Build Coastguard Worker             state.producers()[0].name().find("integrationtest"));
4913*6dbdd20aSAndroid Build Coastguard Worker   bool found_ds = false;
4914*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& ds : state.data_sources()) {
4915*6dbdd20aSAndroid Build Coastguard Worker     if (ds.ds_descriptor().name() == "update_test_data_source") {
4916*6dbdd20aSAndroid Build Coastguard Worker       found_ds = true;
4917*6dbdd20aSAndroid Build Coastguard Worker       perfetto::protos::gen::TrackEventDescriptor ted;
4918*6dbdd20aSAndroid Build Coastguard Worker       auto desc_raw = ds.ds_descriptor().track_event_descriptor_raw();
4919*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(ted.ParseFromArray(desc_raw.data(), desc_raw.size()));
4920*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(ted.available_categories_size(), 1);
4921*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(ted.available_categories()[0].name(), "new_cat");
4922*6dbdd20aSAndroid Build Coastguard Worker     }
4923*6dbdd20aSAndroid Build Coastguard Worker   }
4924*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(found_ds);
4925*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::TracingMuxerImplInternalsForTest::
4926*6dbdd20aSAndroid Build Coastguard Worker       ClearDataSourceTlsStateOnReset<UpdateTestDataSource>();
4927*6dbdd20aSAndroid Build Coastguard Worker }
4928*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,NoFlushFlag)4929*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, NoFlushFlag) {
4930*6dbdd20aSAndroid Build Coastguard Worker   class NoFlushDataSource : public perfetto::DataSource<NoFlushDataSource> {};
4931*6dbdd20aSAndroid Build Coastguard Worker 
4932*6dbdd20aSAndroid Build Coastguard Worker   class FlushDataSource : public perfetto::DataSource<FlushDataSource> {
4933*6dbdd20aSAndroid Build Coastguard Worker    public:
4934*6dbdd20aSAndroid Build Coastguard Worker     void OnFlush(const FlushArgs&) override {}
4935*6dbdd20aSAndroid Build Coastguard Worker   };
4936*6dbdd20aSAndroid Build Coastguard Worker 
4937*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceDescriptor dsd_no_flush;
4938*6dbdd20aSAndroid Build Coastguard Worker   dsd_no_flush.set_name("no_flush_data_source");
4939*6dbdd20aSAndroid Build Coastguard Worker   RegisterDataSource<NoFlushDataSource>(dsd_no_flush);
4940*6dbdd20aSAndroid Build Coastguard Worker 
4941*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceDescriptor dsd_flush;
4942*6dbdd20aSAndroid Build Coastguard Worker   dsd_flush.set_name("flush_data_source");
4943*6dbdd20aSAndroid Build Coastguard Worker   RegisterDataSource<FlushDataSource>(dsd_flush);
4944*6dbdd20aSAndroid Build Coastguard Worker 
4945*6dbdd20aSAndroid Build Coastguard Worker   auto cleanup = MakeCleanup([&] {
4946*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::TracingMuxerImplInternalsForTest::
4947*6dbdd20aSAndroid Build Coastguard Worker         ClearDataSourceTlsStateOnReset<FlushDataSource>();
4948*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::TracingMuxerImplInternalsForTest::
4949*6dbdd20aSAndroid Build Coastguard Worker         ClearDataSourceTlsStateOnReset<NoFlushDataSource>();
4950*6dbdd20aSAndroid Build Coastguard Worker   });
4951*6dbdd20aSAndroid Build Coastguard Worker 
4952*6dbdd20aSAndroid Build Coastguard Worker   auto tracing_session = perfetto::Tracing::NewTrace(/*backend=*/GetParam());
4953*6dbdd20aSAndroid Build Coastguard Worker 
4954*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
4955*6dbdd20aSAndroid Build Coastguard Worker 
4956*6dbdd20aSAndroid Build Coastguard Worker   auto result = tracing_session->QueryServiceStateBlocking();
4957*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TracingServiceState state;
4958*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(result.success);
4959*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(state.ParseFromArray(result.service_state_data.data(),
4960*6dbdd20aSAndroid Build Coastguard Worker                                    result.service_state_data.size()));
4961*6dbdd20aSAndroid Build Coastguard Worker   size_t ds_count_no_flush = 0;
4962*6dbdd20aSAndroid Build Coastguard Worker   size_t ds_count_flush = 0;
4963*6dbdd20aSAndroid Build Coastguard Worker   size_t ds_count_track_event = 0;
4964*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& ds : state.data_sources()) {
4965*6dbdd20aSAndroid Build Coastguard Worker     if (ds.ds_descriptor().name() == "no_flush_data_source") {
4966*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(ds.ds_descriptor().no_flush());
4967*6dbdd20aSAndroid Build Coastguard Worker       ds_count_no_flush++;
4968*6dbdd20aSAndroid Build Coastguard Worker     } else if (ds.ds_descriptor().name() == "flush_data_source") {
4969*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(ds.ds_descriptor().no_flush());
4970*6dbdd20aSAndroid Build Coastguard Worker       ds_count_flush++;
4971*6dbdd20aSAndroid Build Coastguard Worker     } else if (ds.ds_descriptor().name() == "track_event") {
4972*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(ds.ds_descriptor().no_flush());
4973*6dbdd20aSAndroid Build Coastguard Worker       ds_count_track_event++;
4974*6dbdd20aSAndroid Build Coastguard Worker     }
4975*6dbdd20aSAndroid Build Coastguard Worker   }
4976*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(ds_count_no_flush, 1u);
4977*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(ds_count_flush, 1u);
4978*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(ds_count_track_event, 1u);
4979*6dbdd20aSAndroid Build Coastguard Worker 
4980*6dbdd20aSAndroid Build Coastguard Worker   dsd_no_flush.set_track_event_descriptor_raw("DESC_NO");
4981*6dbdd20aSAndroid Build Coastguard Worker   UpdateDataSource<NoFlushDataSource>(dsd_no_flush);
4982*6dbdd20aSAndroid Build Coastguard Worker   dsd_flush.set_track_event_descriptor_raw("DESC_");
4983*6dbdd20aSAndroid Build Coastguard Worker   UpdateDataSource<FlushDataSource>(dsd_flush);
4984*6dbdd20aSAndroid Build Coastguard Worker 
4985*6dbdd20aSAndroid Build Coastguard Worker   result = tracing_session->QueryServiceStateBlocking();
4986*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(result.success);
4987*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(state.ParseFromArray(result.service_state_data.data(),
4988*6dbdd20aSAndroid Build Coastguard Worker                                    result.service_state_data.size()));
4989*6dbdd20aSAndroid Build Coastguard Worker   ds_count_no_flush = 0;
4990*6dbdd20aSAndroid Build Coastguard Worker   ds_count_flush = 0;
4991*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& ds : state.data_sources()) {
4992*6dbdd20aSAndroid Build Coastguard Worker     if (ds.ds_descriptor().name() == "no_flush_data_source") {
4993*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(ds.ds_descriptor().no_flush());
4994*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(ds.ds_descriptor().track_event_descriptor_raw(), "DESC_NO");
4995*6dbdd20aSAndroid Build Coastguard Worker       ds_count_no_flush++;
4996*6dbdd20aSAndroid Build Coastguard Worker     } else if (ds.ds_descriptor().name() == "flush_data_source") {
4997*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(ds.ds_descriptor().no_flush());
4998*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(ds.ds_descriptor().track_event_descriptor_raw(), "DESC_");
4999*6dbdd20aSAndroid Build Coastguard Worker       ds_count_flush++;
5000*6dbdd20aSAndroid Build Coastguard Worker     }
5001*6dbdd20aSAndroid Build Coastguard Worker   }
5002*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(ds_count_no_flush, 1u);
5003*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(ds_count_flush, 1u);
5004*6dbdd20aSAndroid Build Coastguard Worker }
5005*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,LegacyTraceEventsCopyDynamicString)5006*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, LegacyTraceEventsCopyDynamicString) {
5007*6dbdd20aSAndroid Build Coastguard Worker   char ptr1[] = "A1";
5008*6dbdd20aSAndroid Build Coastguard Worker   char ptr2[] = "B1";
5009*6dbdd20aSAndroid Build Coastguard Worker   char arg_name1[] = "C1";
5010*6dbdd20aSAndroid Build Coastguard Worker   char arg_name2[] = "D1";
5011*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
5012*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5013*6dbdd20aSAndroid Build Coastguard Worker   {
5014*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_MARK_WITH_TIMESTAMP0("cat", ptr1, MyTimestamp{0});
5015*6dbdd20aSAndroid Build Coastguard Worker     ptr1[1] = '3';
5016*6dbdd20aSAndroid Build Coastguard Worker     // Old value of event name ("A1") is recorded here in trace.
5017*6dbdd20aSAndroid Build Coastguard Worker     // The reason being, in legacy macros, event name was expected to be static
5018*6dbdd20aSAndroid Build Coastguard Worker     // by default unless `_COPY` version of these macro is used.
5019*6dbdd20aSAndroid Build Coastguard Worker     // Perfetto is caching pointer values and if a event-name-pointer matches an
5020*6dbdd20aSAndroid Build Coastguard Worker     // existing pointer, it ASSUMES the string-value of new pointer is same as
5021*6dbdd20aSAndroid Build Coastguard Worker     // string-value of the cached pointer when it was cached.
5022*6dbdd20aSAndroid Build Coastguard Worker     // and hence it assign the same intern-id to second event.
5023*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_MARK_WITH_TIMESTAMP0("cat", ptr1, MyTimestamp{0});
5024*6dbdd20aSAndroid Build Coastguard Worker   }
5025*6dbdd20aSAndroid Build Coastguard Worker   {
5026*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_COPY_MARK_WITH_TIMESTAMP("cat", ptr2, MyTimestamp{0});
5027*6dbdd20aSAndroid Build Coastguard Worker     ptr2[1] = '4';
5028*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_COPY_MARK_WITH_TIMESTAMP("cat", ptr2, MyTimestamp{0});
5029*6dbdd20aSAndroid Build Coastguard Worker   }
5030*6dbdd20aSAndroid Build Coastguard Worker   {
5031*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT1("cat", "event_name", TRACE_EVENT_FLAG_NONE, arg_name1,
5032*6dbdd20aSAndroid Build Coastguard Worker                          /*arg_value=*/5);
5033*6dbdd20aSAndroid Build Coastguard Worker     arg_name1[1] = '5';
5034*6dbdd20aSAndroid Build Coastguard Worker     // Since we don't use the _COPY version here, this event will record the old
5035*6dbdd20aSAndroid Build Coastguard Worker     // value of arg_name1 (see earlier comment for full explanation).
5036*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT1("cat", "event_name", TRACE_EVENT_FLAG_NONE, arg_name1,
5037*6dbdd20aSAndroid Build Coastguard Worker                          /*arg_value=*/5);
5038*6dbdd20aSAndroid Build Coastguard Worker   }
5039*6dbdd20aSAndroid Build Coastguard Worker   {
5040*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_COPY_INSTANT1("cat", "event_name", TRACE_EVENT_FLAG_NONE,
5041*6dbdd20aSAndroid Build Coastguard Worker                               arg_name2, /*arg_value=*/5);
5042*6dbdd20aSAndroid Build Coastguard Worker     arg_name2[1] = '6';
5043*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_COPY_INSTANT1("cat", "event_name", TRACE_EVENT_FLAG_NONE,
5044*6dbdd20aSAndroid Build Coastguard Worker                               arg_name2, /*arg_value=*/5);
5045*6dbdd20aSAndroid Build Coastguard Worker   }
5046*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5047*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
5048*6dbdd20aSAndroid Build Coastguard Worker       slices,
5049*6dbdd20aSAndroid Build Coastguard Worker       ElementsAre("[track=0]Legacy_R:cat.A1", "[track=0]Legacy_R:cat.A1",
5050*6dbdd20aSAndroid Build Coastguard Worker                   "[track=0]Legacy_R:cat.B1", "[track=0]Legacy_R:cat.B4",
5051*6dbdd20aSAndroid Build Coastguard Worker                   "[track=0]I:cat.event_name(C1=(int)5)",
5052*6dbdd20aSAndroid Build Coastguard Worker                   "[track=0]I:cat.event_name(C1=(int)5)",
5053*6dbdd20aSAndroid Build Coastguard Worker                   "[track=0]I:cat.event_name(D1=(int)5)",
5054*6dbdd20aSAndroid Build Coastguard Worker                   "[track=0]I:cat.event_name(D6=(int)5)"));
5055*6dbdd20aSAndroid Build Coastguard Worker }
5056*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,LegacyTraceEvents)5057*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, LegacyTraceEvents) {
5058*6dbdd20aSAndroid Build Coastguard Worker   auto is_new_session = [] {
5059*6dbdd20aSAndroid Build Coastguard Worker     bool result;
5060*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_IS_NEW_TRACE(&result);
5061*6dbdd20aSAndroid Build Coastguard Worker     return result;
5062*6dbdd20aSAndroid Build Coastguard Worker   };
5063*6dbdd20aSAndroid Build Coastguard Worker 
5064*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
5065*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(is_new_session());
5066*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session =
5067*6dbdd20aSAndroid Build Coastguard Worker       NewTraceWithCategories({"cat", TRACE_DISABLED_BY_DEFAULT("cat")});
5068*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5069*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(is_new_session());
5070*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(is_new_session());
5071*6dbdd20aSAndroid Build Coastguard Worker 
5072*6dbdd20aSAndroid Build Coastguard Worker   // Basic events.
5073*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT0("cat", "LegacyEvent", TRACE_EVENT_SCOPE_GLOBAL);
5074*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN1("cat", "LegacyEvent", "arg", 123);
5075*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END2("cat", "LegacyEvent", "arg", "string", "arg2", 0.123f);
5076*6dbdd20aSAndroid Build Coastguard Worker 
5077*6dbdd20aSAndroid Build Coastguard Worker   // Scoped event.
5078*6dbdd20aSAndroid Build Coastguard Worker   { TRACE_EVENT0("cat", "ScopedLegacyEvent"); }
5079*6dbdd20aSAndroid Build Coastguard Worker 
5080*6dbdd20aSAndroid Build Coastguard Worker   // Event with flow (and disabled category).
5081*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("cat"), "LegacyFlowEvent",
5082*6dbdd20aSAndroid Build Coastguard Worker                          0xdadacafe, TRACE_EVENT_FLAG_FLOW_IN);
5083*6dbdd20aSAndroid Build Coastguard Worker 
5084*6dbdd20aSAndroid Build Coastguard Worker   // Event with timestamp.
5085*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT_WITH_TIMESTAMP0("cat", "LegacyInstantEvent",
5086*6dbdd20aSAndroid Build Coastguard Worker                                       TRACE_EVENT_SCOPE_GLOBAL,
5087*6dbdd20aSAndroid Build Coastguard Worker                                       MyTimestamp{123456789ul});
5088*6dbdd20aSAndroid Build Coastguard Worker 
5089*6dbdd20aSAndroid Build Coastguard Worker   // Event with id.
5090*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER1("cat", "LegacyCounter", 1234);
5091*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER_ID1("cat", "LegacyCounterWithId", 1234, 9000);
5092*6dbdd20aSAndroid Build Coastguard Worker 
5093*6dbdd20aSAndroid Build Coastguard Worker   // Metadata event.
5094*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_METADATA1("cat", "LegacyMetadata", "obsolete", true);
5095*6dbdd20aSAndroid Build Coastguard Worker 
5096*6dbdd20aSAndroid Build Coastguard Worker   // Async events.
5097*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0(
5098*6dbdd20aSAndroid Build Coastguard Worker       "cat", "LegacyAsync", 5678, MyTimestamp{4}, TRACE_EVENT_FLAG_NONE);
5099*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0("cat", "LegacyAsync", 5678,
5100*6dbdd20aSAndroid Build Coastguard Worker                                                  MyTimestamp{5});
5101*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0("cat", "LegacyAsync2", 9000,
5102*6dbdd20aSAndroid Build Coastguard Worker                                                TRACE_EVENT_FLAG_NONE);
5103*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_END_WITH_FLAGS0("cat", "LegacyAsync2", 9000,
5104*6dbdd20aSAndroid Build Coastguard Worker                                              TRACE_EVENT_FLAG_NONE);
5105*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0("cat", "LegacyAsync3", 9001,
5106*6dbdd20aSAndroid Build Coastguard Worker                                                TRACE_EVENT_FLAG_NONE);
5107*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(
5108*6dbdd20aSAndroid Build Coastguard Worker       "cat", "LegacyAsync3", 9001, MyTimestamp{6}, TRACE_EVENT_FLAG_NONE);
5109*6dbdd20aSAndroid Build Coastguard Worker 
5110*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5111*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
5112*6dbdd20aSAndroid Build Coastguard Worker       slices,
5113*6dbdd20aSAndroid Build Coastguard Worker       ElementsAre(
5114*6dbdd20aSAndroid Build Coastguard Worker           "[track=0]I:cat.LegacyEvent", "B:cat.LegacyEvent(arg=(int)123)",
5115*6dbdd20aSAndroid Build Coastguard Worker           "E(arg=(string)string,arg2=(double)0.123)", "B:cat.ScopedLegacyEvent",
5116*6dbdd20aSAndroid Build Coastguard Worker           "E",
5117*6dbdd20aSAndroid Build Coastguard Worker           "B(bind_id=3671771902)(flow_direction=1):disabled-by-default-cat."
5118*6dbdd20aSAndroid Build Coastguard Worker           "LegacyFlowEvent",
5119*6dbdd20aSAndroid Build Coastguard Worker           "[track=0]I:cat.LegacyInstantEvent",
5120*6dbdd20aSAndroid Build Coastguard Worker           "[track=0]Legacy_C:cat.LegacyCounter(value=(int)1234)",
5121*6dbdd20aSAndroid Build Coastguard Worker           "[track=0]Legacy_C(unscoped_id=1234):cat.LegacyCounterWithId(value=("
5122*6dbdd20aSAndroid Build Coastguard Worker           "int)9000)",
5123*6dbdd20aSAndroid Build Coastguard Worker           "[track=0]Legacy_M:cat.LegacyMetadata",
5124*6dbdd20aSAndroid Build Coastguard Worker           "[track=0]Legacy_b(unscoped_id=5678):cat.LegacyAsync",
5125*6dbdd20aSAndroid Build Coastguard Worker           "[track=0]Legacy_e(unscoped_id=5678):cat.LegacyAsync",
5126*6dbdd20aSAndroid Build Coastguard Worker           "[track=0]Legacy_b(unscoped_id=9000):cat.LegacyAsync2",
5127*6dbdd20aSAndroid Build Coastguard Worker           "[track=0]Legacy_e(unscoped_id=9000):cat.LegacyAsync2",
5128*6dbdd20aSAndroid Build Coastguard Worker           "[track=0]Legacy_b(unscoped_id=9001):cat.LegacyAsync3",
5129*6dbdd20aSAndroid Build Coastguard Worker           "[track=0]Legacy_e(unscoped_id=9001):cat.LegacyAsync3"));
5130*6dbdd20aSAndroid Build Coastguard Worker }
5131*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,LegacyTraceEventsAndClockSnapshots)5132*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, LegacyTraceEventsAndClockSnapshots) {
5133*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
5134*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5135*6dbdd20aSAndroid Build Coastguard Worker 
5136*6dbdd20aSAndroid Build Coastguard Worker   {
5137*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "LegacyAsync", 5678);
5138*6dbdd20aSAndroid Build Coastguard Worker 
5139*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::TracingMuxerImplInternalsForTest::ClearIncrementalState();
5140*6dbdd20aSAndroid Build Coastguard Worker 
5141*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(
5142*6dbdd20aSAndroid Build Coastguard Worker         "cat", "LegacyAsyncWithTimestamp", 5678, MyTimestamp{1});
5143*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(
5144*6dbdd20aSAndroid Build Coastguard Worker         "cat", "LegacyAsyncWithTimestamp", 5678, MyTimestamp{2});
5145*6dbdd20aSAndroid Build Coastguard Worker 
5146*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::TracingMuxerImplInternalsForTest::ClearIncrementalState();
5147*6dbdd20aSAndroid Build Coastguard Worker 
5148*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_NESTABLE_ASYNC_END0("cat", "LegacyAsync", 5678);
5149*6dbdd20aSAndroid Build Coastguard Worker   }
5150*6dbdd20aSAndroid Build Coastguard Worker 
5151*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
5152*6dbdd20aSAndroid Build Coastguard Worker 
5153*6dbdd20aSAndroid Build Coastguard Worker   // Check that clock snapshots are monotonic (per sequence) and don't contain
5154*6dbdd20aSAndroid Build Coastguard Worker   // timestamps from trace events with explicit timestamps.
5155*6dbdd20aSAndroid Build Coastguard Worker   struct ClockPerSequence {
5156*6dbdd20aSAndroid Build Coastguard Worker     uint64_t seq_id = 0;
5157*6dbdd20aSAndroid Build Coastguard Worker     uint64_t clock_id = 0;
5158*6dbdd20aSAndroid Build Coastguard Worker     bool operator<(const struct ClockPerSequence& other) const {
5159*6dbdd20aSAndroid Build Coastguard Worker       return std::tie(seq_id, clock_id) <
5160*6dbdd20aSAndroid Build Coastguard Worker              std::tie(other.seq_id, other.clock_id);
5161*6dbdd20aSAndroid Build Coastguard Worker     }
5162*6dbdd20aSAndroid Build Coastguard Worker   };
5163*6dbdd20aSAndroid Build Coastguard Worker   std::map<ClockPerSequence, uint64_t> last_clock_ts;
5164*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
5165*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_clock_snapshot()) {
5166*6dbdd20aSAndroid Build Coastguard Worker       for (auto& clock : packet.clock_snapshot().clocks()) {
5167*6dbdd20aSAndroid Build Coastguard Worker         if (!clock.is_incremental()) {
5168*6dbdd20aSAndroid Build Coastguard Worker           uint64_t ts = clock.timestamp();
5169*6dbdd20aSAndroid Build Coastguard Worker           ClockPerSequence c;
5170*6dbdd20aSAndroid Build Coastguard Worker           c.seq_id = packet.trusted_packet_sequence_id();
5171*6dbdd20aSAndroid Build Coastguard Worker           c.clock_id = clock.clock_id();
5172*6dbdd20aSAndroid Build Coastguard Worker 
5173*6dbdd20aSAndroid Build Coastguard Worker           uint64_t& last = last_clock_ts[c];
5174*6dbdd20aSAndroid Build Coastguard Worker 
5175*6dbdd20aSAndroid Build Coastguard Worker           EXPECT_LE(last, ts)
5176*6dbdd20aSAndroid Build Coastguard Worker               << "This sequence:" << c.seq_id << " clock_id:" << c.clock_id;
5177*6dbdd20aSAndroid Build Coastguard Worker           last = ts;
5178*6dbdd20aSAndroid Build Coastguard Worker         }
5179*6dbdd20aSAndroid Build Coastguard Worker       }
5180*6dbdd20aSAndroid Build Coastguard Worker 
5181*6dbdd20aSAndroid Build Coastguard Worker       // Events that don't use explicit timestamps should have exactly the same
5182*6dbdd20aSAndroid Build Coastguard Worker       // timestamp as in the snapshot (i.e. the relative ts of 0).
5183*6dbdd20aSAndroid Build Coastguard Worker       // Here we assume that timestamps are incremental by default.
5184*6dbdd20aSAndroid Build Coastguard Worker       if (!packet.has_timestamp_clock_id()) {
5185*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(packet.timestamp(), 0u);
5186*6dbdd20aSAndroid Build Coastguard Worker       }
5187*6dbdd20aSAndroid Build Coastguard Worker     }
5188*6dbdd20aSAndroid Build Coastguard Worker   }
5189*6dbdd20aSAndroid Build Coastguard Worker }
5190*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,LegacyTraceEventsWithCustomAnnotation)5191*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, LegacyTraceEventsWithCustomAnnotation) {
5192*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
5193*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
5194*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5195*6dbdd20aSAndroid Build Coastguard Worker 
5196*6dbdd20aSAndroid Build Coastguard Worker   MyDebugAnnotation annotation;
5197*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN1("cat", "LegacyEvent", "arg", annotation);
5198*6dbdd20aSAndroid Build Coastguard Worker 
5199*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<MyDebugAnnotation> owned_annotation(new MyDebugAnnotation());
5200*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN1("cat", "LegacyEvent", "arg", std::move(owned_annotation));
5201*6dbdd20aSAndroid Build Coastguard Worker 
5202*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5203*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices,
5204*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:cat.LegacyEvent(arg=(json){\"key\": 123})",
5205*6dbdd20aSAndroid Build Coastguard Worker                           "B:cat.LegacyEvent(arg=(json){\"key\": 123})"));
5206*6dbdd20aSAndroid Build Coastguard Worker }
5207*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,LegacyTraceEventsWithConcurrentSessions)5208*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, LegacyTraceEventsWithConcurrentSessions) {
5209*6dbdd20aSAndroid Build Coastguard Worker   // Make sure that a uniquely owned debug annotation can be written into
5210*6dbdd20aSAndroid Build Coastguard Worker   // multiple concurrent tracing sessions.
5211*6dbdd20aSAndroid Build Coastguard Worker 
5212*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
5213*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5214*6dbdd20aSAndroid Build Coastguard Worker 
5215*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session2 = NewTraceWithCategories({"cat"});
5216*6dbdd20aSAndroid Build Coastguard Worker   tracing_session2->get()->StartBlocking();
5217*6dbdd20aSAndroid Build Coastguard Worker 
5218*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<MyDebugAnnotation> owned_annotation(new MyDebugAnnotation());
5219*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN1("cat", "LegacyEvent", "arg", std::move(owned_annotation));
5220*6dbdd20aSAndroid Build Coastguard Worker 
5221*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5222*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices,
5223*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:cat.LegacyEvent(arg=(json){\"key\": 123})"));
5224*6dbdd20aSAndroid Build Coastguard Worker 
5225*6dbdd20aSAndroid Build Coastguard Worker   slices = StopSessionAndReadSlicesFromTrace(tracing_session2);
5226*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices,
5227*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B:cat.LegacyEvent(arg=(json){\"key\": 123})"));
5228*6dbdd20aSAndroid Build Coastguard Worker }
5229*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,LegacyTraceEventsWithId)5230*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, LegacyTraceEventsWithId) {
5231*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
5232*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5233*6dbdd20aSAndroid Build Coastguard Worker 
5234*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_ASYNC_BEGIN0("cat", "UnscopedId", 0x1000);
5235*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_ASYNC_BEGIN0("cat", "LocalId", TRACE_ID_LOCAL(0x2000));
5236*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_ASYNC_BEGIN0("cat", "GlobalId", TRACE_ID_GLOBAL(0x3000));
5237*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_ASYNC_BEGIN0(
5238*6dbdd20aSAndroid Build Coastguard Worker       "cat", "WithScope",
5239*6dbdd20aSAndroid Build Coastguard Worker       TRACE_ID_WITH_SCOPE("scope string", TRACE_ID_GLOBAL(0x4000)));
5240*6dbdd20aSAndroid Build Coastguard Worker 
5241*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5242*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices,
5243*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("[track=0]Legacy_S(unscoped_id=4096):cat.UnscopedId",
5244*6dbdd20aSAndroid Build Coastguard Worker                           "[track=0]Legacy_S(local_id=8192):cat.LocalId",
5245*6dbdd20aSAndroid Build Coastguard Worker                           "[track=0]Legacy_S(global_id=12288):cat.GlobalId",
5246*6dbdd20aSAndroid Build Coastguard Worker                           "[track=0]Legacy_S(global_id=16384)(id_scope=\"scope "
5247*6dbdd20aSAndroid Build Coastguard Worker                           "string\"):cat.WithScope"));
5248*6dbdd20aSAndroid Build Coastguard Worker }
5249*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,NestableAsyncTraceEvent)5250*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, NestableAsyncTraceEvent) {
5251*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
5252*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5253*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "foo",
5254*6dbdd20aSAndroid Build Coastguard Worker                                     TRACE_ID_WITH_SCOPE("foo", 1));
5255*6dbdd20aSAndroid Build Coastguard Worker   // Same id, different scope.
5256*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "bar",
5257*6dbdd20aSAndroid Build Coastguard Worker                                     TRACE_ID_WITH_SCOPE("bar", 1));
5258*6dbdd20aSAndroid Build Coastguard Worker   // Same scope, different id.
5259*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "bar",
5260*6dbdd20aSAndroid Build Coastguard Worker                                     TRACE_ID_WITH_SCOPE("bar", 2));
5261*6dbdd20aSAndroid Build Coastguard Worker 
5262*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_END0("cat", "bar", TRACE_ID_WITH_SCOPE("bar", 2));
5263*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_END0("cat", "bar", TRACE_ID_WITH_SCOPE("bar", 1));
5264*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_END0("cat", "foo", TRACE_ID_WITH_SCOPE("foo", 1));
5265*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
5266*6dbdd20aSAndroid Build Coastguard Worker   using LegacyEvent = perfetto::protos::gen::TrackEvent::LegacyEvent;
5267*6dbdd20aSAndroid Build Coastguard Worker   std::vector<const LegacyEvent*> legacy_events;
5268*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
5269*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_event() && packet.track_event().has_legacy_event()) {
5270*6dbdd20aSAndroid Build Coastguard Worker       legacy_events.push_back(&packet.track_event().legacy_event());
5271*6dbdd20aSAndroid Build Coastguard Worker     }
5272*6dbdd20aSAndroid Build Coastguard Worker   }
5273*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(6u, legacy_events.size());
5274*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("foo", legacy_events[0]->id_scope());
5275*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("bar", legacy_events[1]->id_scope());
5276*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("bar", legacy_events[2]->id_scope());
5277*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("bar", legacy_events[3]->id_scope());
5278*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("bar", legacy_events[4]->id_scope());
5279*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("foo", legacy_events[5]->id_scope());
5280*6dbdd20aSAndroid Build Coastguard Worker 
5281*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(legacy_events[0]->unscoped_id(), legacy_events[5]->unscoped_id());
5282*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(legacy_events[1]->unscoped_id(), legacy_events[4]->unscoped_id());
5283*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(legacy_events[2]->unscoped_id(), legacy_events[3]->unscoped_id());
5284*6dbdd20aSAndroid Build Coastguard Worker 
5285*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(legacy_events[0]->unscoped_id(), legacy_events[1]->unscoped_id());
5286*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(legacy_events[1]->unscoped_id(), legacy_events[2]->unscoped_id());
5287*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(legacy_events[2]->unscoped_id(), legacy_events[0]->unscoped_id());
5288*6dbdd20aSAndroid Build Coastguard Worker }
5289*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,LegacyTraceEventsWithFlow)5290*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, LegacyTraceEventsWithFlow) {
5291*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
5292*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5293*6dbdd20aSAndroid Build Coastguard Worker 
5294*6dbdd20aSAndroid Build Coastguard Worker   const uint64_t flow_id = 1234;
5295*6dbdd20aSAndroid Build Coastguard Worker   {
5296*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_WITH_FLOW1("cat", "LatencyInfo.Flow", TRACE_ID_GLOBAL(flow_id),
5297*6dbdd20aSAndroid Build Coastguard Worker                            TRACE_EVENT_FLAG_FLOW_OUT, "step", "Begin");
5298*6dbdd20aSAndroid Build Coastguard Worker   }
5299*6dbdd20aSAndroid Build Coastguard Worker 
5300*6dbdd20aSAndroid Build Coastguard Worker   {
5301*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_WITH_FLOW2("cat", "LatencyInfo.Flow", TRACE_ID_GLOBAL(flow_id),
5302*6dbdd20aSAndroid Build Coastguard Worker                            TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
5303*6dbdd20aSAndroid Build Coastguard Worker                            "step", "Middle", "value", false);
5304*6dbdd20aSAndroid Build Coastguard Worker   }
5305*6dbdd20aSAndroid Build Coastguard Worker 
5306*6dbdd20aSAndroid Build Coastguard Worker   {
5307*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_WITH_FLOW1("cat", "LatencyInfo.Flow", TRACE_ID_GLOBAL(flow_id),
5308*6dbdd20aSAndroid Build Coastguard Worker                            TRACE_EVENT_FLAG_FLOW_IN, "step", "End");
5309*6dbdd20aSAndroid Build Coastguard Worker   }
5310*6dbdd20aSAndroid Build Coastguard Worker 
5311*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5312*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices,
5313*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("B(bind_id=1234)(flow_direction=2):cat.LatencyInfo."
5314*6dbdd20aSAndroid Build Coastguard Worker                           "Flow(step=(string)Begin)",
5315*6dbdd20aSAndroid Build Coastguard Worker                           "E",
5316*6dbdd20aSAndroid Build Coastguard Worker                           "B(bind_id=1234)(flow_direction=3):cat.LatencyInfo."
5317*6dbdd20aSAndroid Build Coastguard Worker                           "Flow(step=(string)Middle,value=(bool)0)",
5318*6dbdd20aSAndroid Build Coastguard Worker                           "E",
5319*6dbdd20aSAndroid Build Coastguard Worker                           "B(bind_id=1234)(flow_direction=1):cat.LatencyInfo."
5320*6dbdd20aSAndroid Build Coastguard Worker                           "Flow(step=(string)End)",
5321*6dbdd20aSAndroid Build Coastguard Worker                           "E"));
5322*6dbdd20aSAndroid Build Coastguard Worker }
5323*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,LegacyCategoryGroupEnabledState)5324*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, LegacyCategoryGroupEnabledState) {
5325*6dbdd20aSAndroid Build Coastguard Worker   bool foo_status;
5326*6dbdd20aSAndroid Build Coastguard Worker   bool bar_status;
5327*6dbdd20aSAndroid Build Coastguard Worker   bool dynamic_status;
5328*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_CATEGORY_GROUP_ENABLED("foo", &foo_status);
5329*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_CATEGORY_GROUP_ENABLED("bar", &bar_status);
5330*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_CATEGORY_GROUP_ENABLED("dynamic", &dynamic_status);
5331*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(foo_status);
5332*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(bar_status);
5333*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(dynamic_status);
5334*6dbdd20aSAndroid Build Coastguard Worker 
5335*6dbdd20aSAndroid Build Coastguard Worker   const uint8_t* foo_enabled =
5336*6dbdd20aSAndroid Build Coastguard Worker       TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("foo");
5337*6dbdd20aSAndroid Build Coastguard Worker   const uint8_t* bar_enabled =
5338*6dbdd20aSAndroid Build Coastguard Worker       TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("bar");
5339*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(*foo_enabled);
5340*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(*bar_enabled);
5341*6dbdd20aSAndroid Build Coastguard Worker 
5342*6dbdd20aSAndroid Build Coastguard Worker   // The category group enabled pointer can also be retrieved with a
5343*6dbdd20aSAndroid Build Coastguard Worker   // runtime-computed category name.
5344*6dbdd20aSAndroid Build Coastguard Worker   std::string computed_cat("cat");
5345*6dbdd20aSAndroid Build Coastguard Worker   const uint8_t* computed_enabled =
5346*6dbdd20aSAndroid Build Coastguard Worker       TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(computed_cat.c_str());
5347*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(*computed_enabled);
5348*6dbdd20aSAndroid Build Coastguard Worker 
5349*6dbdd20aSAndroid Build Coastguard Worker   // The enabled pointers can be converted back to category names.
5350*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("foo", TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(foo_enabled));
5351*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("bar", TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(bar_enabled));
5352*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ("cat", TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(computed_enabled));
5353*6dbdd20aSAndroid Build Coastguard Worker 
5354*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo", "dynamic", "cat"});
5355*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5356*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_CATEGORY_GROUP_ENABLED("foo", &foo_status);
5357*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_CATEGORY_GROUP_ENABLED("bar", &bar_status);
5358*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_CATEGORY_GROUP_ENABLED("dynamic", &dynamic_status);
5359*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(foo_status);
5360*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(bar_status);
5361*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(dynamic_status);
5362*6dbdd20aSAndroid Build Coastguard Worker 
5363*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(*foo_enabled);
5364*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(*bar_enabled);
5365*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(*computed_enabled);
5366*6dbdd20aSAndroid Build Coastguard Worker 
5367*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
5368*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_CATEGORY_GROUP_ENABLED("foo", &foo_status);
5369*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_CATEGORY_GROUP_ENABLED("bar", &bar_status);
5370*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_CATEGORY_GROUP_ENABLED("dynamic", &dynamic_status);
5371*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(foo_status);
5372*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(bar_status);
5373*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(dynamic_status);
5374*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(*foo_enabled);
5375*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(*bar_enabled);
5376*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(*computed_enabled);
5377*6dbdd20aSAndroid Build Coastguard Worker }
5378*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,CategoryEnabledState)5379*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, CategoryEnabledState) {
5380*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DynamicCategory dynamic{"dynamic"};
5381*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5382*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("bar"));
5383*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("red,green,blue,foo"));
5384*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic"));
5385*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic_2"));
5386*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED(dynamic));
5387*6dbdd20aSAndroid Build Coastguard Worker 
5388*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo", "dynamic"});
5389*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5390*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5391*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("bar"));
5392*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("red,green,blue,foo"));
5393*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("dynamic"));
5394*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic_2"));
5395*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED(dynamic));
5396*6dbdd20aSAndroid Build Coastguard Worker 
5397*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
5398*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5399*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("bar"));
5400*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("red,green,blue,foo"));
5401*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic"));
5402*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED("dynamic_2"));
5403*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(TRACE_EVENT_CATEGORY_ENABLED(dynamic));
5404*6dbdd20aSAndroid Build Coastguard Worker }
5405*6dbdd20aSAndroid Build Coastguard Worker 
5406*6dbdd20aSAndroid Build Coastguard Worker class TestInterceptor : public perfetto::Interceptor<TestInterceptor> {
5407*6dbdd20aSAndroid Build Coastguard Worker  public:
5408*6dbdd20aSAndroid Build Coastguard Worker   static TestInterceptor* instance;
5409*6dbdd20aSAndroid Build Coastguard Worker 
5410*6dbdd20aSAndroid Build Coastguard Worker   struct ThreadLocalState : public perfetto::InterceptorBase::ThreadLocalState {
ThreadLocalState__anonfc73210d0111::TestInterceptor::ThreadLocalState5411*6dbdd20aSAndroid Build Coastguard Worker     ThreadLocalState(ThreadLocalStateArgs& args) {
5412*6dbdd20aSAndroid Build Coastguard Worker       // Test accessing instance state from the TLS constructor.
5413*6dbdd20aSAndroid Build Coastguard Worker       if (auto self = args.GetInterceptorLocked()) {
5414*6dbdd20aSAndroid Build Coastguard Worker         self->tls_initialized = true;
5415*6dbdd20aSAndroid Build Coastguard Worker       }
5416*6dbdd20aSAndroid Build Coastguard Worker     }
5417*6dbdd20aSAndroid Build Coastguard Worker 
5418*6dbdd20aSAndroid Build Coastguard Worker     std::map<uint64_t, std::string> event_names;
5419*6dbdd20aSAndroid Build Coastguard Worker   };
5420*6dbdd20aSAndroid Build Coastguard Worker 
TestInterceptor(const std::string & constructor_arg)5421*6dbdd20aSAndroid Build Coastguard Worker   TestInterceptor(const std::string& constructor_arg) {
5422*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(constructor_arg, "Constructor argument");
5423*6dbdd20aSAndroid Build Coastguard Worker     // Note: some tests in this suite register multiple track event data
5424*6dbdd20aSAndroid Build Coastguard Worker     // sources. We only track data for the first in this test.
5425*6dbdd20aSAndroid Build Coastguard Worker     if (!instance)
5426*6dbdd20aSAndroid Build Coastguard Worker       instance = this;
5427*6dbdd20aSAndroid Build Coastguard Worker   }
5428*6dbdd20aSAndroid Build Coastguard Worker 
~TestInterceptor()5429*6dbdd20aSAndroid Build Coastguard Worker   ~TestInterceptor() override {
5430*6dbdd20aSAndroid Build Coastguard Worker     if (instance != this)
5431*6dbdd20aSAndroid Build Coastguard Worker       return;
5432*6dbdd20aSAndroid Build Coastguard Worker     instance = nullptr;
5433*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(setup_called);
5434*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(start_called);
5435*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(stop_called);
5436*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(tls_initialized);
5437*6dbdd20aSAndroid Build Coastguard Worker   }
5438*6dbdd20aSAndroid Build Coastguard Worker 
OnSetup(const SetupArgs &)5439*6dbdd20aSAndroid Build Coastguard Worker   void OnSetup(const SetupArgs&) override {
5440*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(setup_called);
5441*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(start_called);
5442*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(stop_called);
5443*6dbdd20aSAndroid Build Coastguard Worker     setup_called = true;
5444*6dbdd20aSAndroid Build Coastguard Worker   }
5445*6dbdd20aSAndroid Build Coastguard Worker 
OnStart(const StartArgs &)5446*6dbdd20aSAndroid Build Coastguard Worker   void OnStart(const StartArgs&) override {
5447*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(setup_called);
5448*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(start_called);
5449*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(stop_called);
5450*6dbdd20aSAndroid Build Coastguard Worker     start_called = true;
5451*6dbdd20aSAndroid Build Coastguard Worker   }
5452*6dbdd20aSAndroid Build Coastguard Worker 
OnStop(const StopArgs &)5453*6dbdd20aSAndroid Build Coastguard Worker   void OnStop(const StopArgs&) override {
5454*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(setup_called);
5455*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(start_called);
5456*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(stop_called);
5457*6dbdd20aSAndroid Build Coastguard Worker     stop_called = true;
5458*6dbdd20aSAndroid Build Coastguard Worker   }
5459*6dbdd20aSAndroid Build Coastguard Worker 
OnTracePacket(InterceptorContext context)5460*6dbdd20aSAndroid Build Coastguard Worker   static void OnTracePacket(InterceptorContext context) {
5461*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::pbzero::TracePacket::Decoder packet(
5462*6dbdd20aSAndroid Build Coastguard Worker         context.packet_data.data, context.packet_data.size);
5463*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(packet.trusted_packet_sequence_id() > 0);
5464*6dbdd20aSAndroid Build Coastguard Worker     {
5465*6dbdd20aSAndroid Build Coastguard Worker       auto self = context.GetInterceptorLocked();
5466*6dbdd20aSAndroid Build Coastguard Worker       ASSERT_TRUE(self);
5467*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(self->setup_called);
5468*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(self->start_called);
5469*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(self->stop_called);
5470*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(self->tls_initialized);
5471*6dbdd20aSAndroid Build Coastguard Worker     }
5472*6dbdd20aSAndroid Build Coastguard Worker 
5473*6dbdd20aSAndroid Build Coastguard Worker     auto& tls = context.GetThreadLocalState();
5474*6dbdd20aSAndroid Build Coastguard Worker     if (packet.sequence_flags() &
5475*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
5476*6dbdd20aSAndroid Build Coastguard Worker       tls.event_names.clear();
5477*6dbdd20aSAndroid Build Coastguard Worker     }
5478*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_interned_data()) {
5479*6dbdd20aSAndroid Build Coastguard Worker       perfetto::protos::pbzero::InternedData::Decoder interned_data(
5480*6dbdd20aSAndroid Build Coastguard Worker           packet.interned_data());
5481*6dbdd20aSAndroid Build Coastguard Worker       for (auto it = interned_data.event_names(); it; it++) {
5482*6dbdd20aSAndroid Build Coastguard Worker         perfetto::protos::pbzero::EventName::Decoder entry(*it);
5483*6dbdd20aSAndroid Build Coastguard Worker         tls.event_names[entry.iid()] = entry.name().ToStdString();
5484*6dbdd20aSAndroid Build Coastguard Worker       }
5485*6dbdd20aSAndroid Build Coastguard Worker     }
5486*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_event()) {
5487*6dbdd20aSAndroid Build Coastguard Worker       perfetto::protos::pbzero::TrackEvent::Decoder track_event(
5488*6dbdd20aSAndroid Build Coastguard Worker           packet.track_event());
5489*6dbdd20aSAndroid Build Coastguard Worker       uint64_t name_iid = track_event.name_iid();
5490*6dbdd20aSAndroid Build Coastguard Worker       auto self = context.GetInterceptorLocked();
5491*6dbdd20aSAndroid Build Coastguard Worker       self->events.push_back(tls.event_names[name_iid].c_str());
5492*6dbdd20aSAndroid Build Coastguard Worker     }
5493*6dbdd20aSAndroid Build Coastguard Worker   }
5494*6dbdd20aSAndroid Build Coastguard Worker 
5495*6dbdd20aSAndroid Build Coastguard Worker   bool setup_called = false;
5496*6dbdd20aSAndroid Build Coastguard Worker   bool start_called = false;
5497*6dbdd20aSAndroid Build Coastguard Worker   bool stop_called = false;
5498*6dbdd20aSAndroid Build Coastguard Worker   bool tls_initialized = false;
5499*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> events;
5500*6dbdd20aSAndroid Build Coastguard Worker };
5501*6dbdd20aSAndroid Build Coastguard Worker 
5502*6dbdd20aSAndroid Build Coastguard Worker TestInterceptor* TestInterceptor::instance;
5503*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TracePacketInterception)5504*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TracePacketInterception) {
5505*6dbdd20aSAndroid Build Coastguard Worker   perfetto::InterceptorDescriptor desc;
5506*6dbdd20aSAndroid Build Coastguard Worker   desc.set_name("test_interceptor");
5507*6dbdd20aSAndroid Build Coastguard Worker   TestInterceptor::Register(desc, std::string("Constructor argument"));
5508*6dbdd20aSAndroid Build Coastguard Worker 
5509*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
5510*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
5511*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
5512*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
5513*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
5514*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->mutable_interceptor_config()->set_name("test_interceptor");
5515*6dbdd20aSAndroid Build Coastguard Worker 
5516*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
5517*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5518*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(0u, TestInterceptor::instance->events.size());
5519*6dbdd20aSAndroid Build Coastguard Worker 
5520*6dbdd20aSAndroid Build Coastguard Worker   // The interceptor should see an event immediately without any explicit
5521*6dbdd20aSAndroid Build Coastguard Worker   // flushing.
5522*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Hip");
5523*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(TestInterceptor::instance->events, ElementsAre("Hip"));
5524*6dbdd20aSAndroid Build Coastguard Worker 
5525*6dbdd20aSAndroid Build Coastguard Worker   // Emit another event with the same title to test interning.
5526*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Hip");
5527*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(TestInterceptor::instance->events, ElementsAre("Hip", "Hip"));
5528*6dbdd20aSAndroid Build Coastguard Worker 
5529*6dbdd20aSAndroid Build Coastguard Worker   // Emit an event from another thread. It should still reach the same
5530*6dbdd20aSAndroid Build Coastguard Worker   // interceptor instance.
5531*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([] { TRACE_EVENT_BEGIN("foo", "Hooray"); });
5532*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
5533*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(TestInterceptor::instance->events,
5534*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("Hip", "Hip", "Hooray"));
5535*6dbdd20aSAndroid Build Coastguard Worker 
5536*6dbdd20aSAndroid Build Coastguard Worker   // Emit a packet that spans multiple segments and must be stitched together.
5537*6dbdd20aSAndroid Build Coastguard Worker   TestInterceptor::instance->events.clear();
5538*6dbdd20aSAndroid Build Coastguard Worker   static char long_title[8192];
5539*6dbdd20aSAndroid Build Coastguard Worker   memset(long_title, 'a', sizeof(long_title) - 1);
5540*6dbdd20aSAndroid Build Coastguard Worker   long_title[sizeof(long_title) - 1] = 0;
5541*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", long_title);
5542*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(TestInterceptor::instance->events, ElementsAre(long_title));
5543*6dbdd20aSAndroid Build Coastguard Worker 
5544*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
5545*6dbdd20aSAndroid Build Coastguard Worker }
5546*6dbdd20aSAndroid Build Coastguard Worker 
EmitConsoleEvents()5547*6dbdd20aSAndroid Build Coastguard Worker void EmitConsoleEvents() {
5548*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "Instant event");
5549*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT("foo", "Scoped event");
5550*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Nested event");
5551*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "Instant event");
5552*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("foo", "Annotated event", "foo", 1, "bar", "hello");
5553*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
5554*6dbdd20aSAndroid Build Coastguard Worker   uint64_t async_id = 4004;
5555*6dbdd20aSAndroid Build Coastguard Worker   auto track = perfetto::Track(async_id, perfetto::ThreadTrack::Current());
5556*6dbdd20aSAndroid Build Coastguard Worker   auto desc = track.Serialize();
5557*6dbdd20aSAndroid Build Coastguard Worker   desc.set_name("AsyncTrack");
5558*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::SetTrackDescriptor(track, std::move(desc));
5559*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "AsyncEvent", track);
5560*6dbdd20aSAndroid Build Coastguard Worker 
5561*6dbdd20aSAndroid Build Coastguard Worker   std::thread thread([&] {
5562*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT("foo", "EventFromAnotherThread");
5563*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT("foo", "Instant event");
5564*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_END("test", track);
5565*6dbdd20aSAndroid Build Coastguard Worker   });
5566*6dbdd20aSAndroid Build Coastguard Worker   thread.join();
5567*6dbdd20aSAndroid Build Coastguard Worker 
5568*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT(
5569*6dbdd20aSAndroid Build Coastguard Worker       "foo", "More annotations", "dict",
5570*6dbdd20aSAndroid Build Coastguard Worker       [](perfetto::TracedValue context) {
5571*6dbdd20aSAndroid Build Coastguard Worker         auto dict = std::move(context).WriteDictionary();
5572*6dbdd20aSAndroid Build Coastguard Worker         dict.Add("key", 123);
5573*6dbdd20aSAndroid Build Coastguard Worker       },
5574*6dbdd20aSAndroid Build Coastguard Worker       "array",
5575*6dbdd20aSAndroid Build Coastguard Worker       [](perfetto::TracedValue context) {
5576*6dbdd20aSAndroid Build Coastguard Worker         auto array = std::move(context).WriteArray();
5577*6dbdd20aSAndroid Build Coastguard Worker         array.Append("first");
5578*6dbdd20aSAndroid Build Coastguard Worker         array.Append("second");
5579*6dbdd20aSAndroid Build Coastguard Worker       });
5580*6dbdd20aSAndroid Build Coastguard Worker }
5581*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ConsoleInterceptorPrint)5582*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ConsoleInterceptorPrint) {
5583*6dbdd20aSAndroid Build Coastguard Worker   perfetto::ConsoleInterceptor::Register();
5584*6dbdd20aSAndroid Build Coastguard Worker 
5585*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
5586*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
5587*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
5588*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
5589*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
5590*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->mutable_interceptor_config()->set_name("console");
5591*6dbdd20aSAndroid Build Coastguard Worker 
5592*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
5593*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5594*6dbdd20aSAndroid Build Coastguard Worker   EmitConsoleEvents();
5595*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
5596*6dbdd20aSAndroid Build Coastguard Worker }
5597*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ConsoleInterceptorVerify)5598*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ConsoleInterceptorVerify) {
5599*6dbdd20aSAndroid Build Coastguard Worker   perfetto::ConsoleInterceptor::Register();
5600*6dbdd20aSAndroid Build Coastguard Worker   auto temp_file = perfetto::test::CreateTempFile();
5601*6dbdd20aSAndroid Build Coastguard Worker   perfetto::ConsoleInterceptor::SetOutputFdForTesting(temp_file.fd);
5602*6dbdd20aSAndroid Build Coastguard Worker 
5603*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
5604*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
5605*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
5606*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
5607*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
5608*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->mutable_interceptor_config()->set_name("console");
5609*6dbdd20aSAndroid Build Coastguard Worker 
5610*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
5611*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5612*6dbdd20aSAndroid Build Coastguard Worker   EmitConsoleEvents();
5613*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
5614*6dbdd20aSAndroid Build Coastguard Worker   perfetto::ConsoleInterceptor::SetOutputFdForTesting(0);
5615*6dbdd20aSAndroid Build Coastguard Worker 
5616*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> lines;
5617*6dbdd20aSAndroid Build Coastguard Worker   FILE* f = fdopen(temp_file.fd, "r");
5618*6dbdd20aSAndroid Build Coastguard Worker   fseek(f, 0u, SEEK_SET);
5619*6dbdd20aSAndroid Build Coastguard Worker   std::array<char, 128> line{};
5620*6dbdd20aSAndroid Build Coastguard Worker   while (fgets(line.data(), line.size(), f)) {
5621*6dbdd20aSAndroid Build Coastguard Worker     // Ignore timestamps and process/thread ids.
5622*6dbdd20aSAndroid Build Coastguard Worker     std::string s(line.data() + 28);
5623*6dbdd20aSAndroid Build Coastguard Worker     // Filter out durations.
5624*6dbdd20aSAndroid Build Coastguard Worker     s = std::regex_replace(s, std::regex(" [+][0-9]*ms"), "");
5625*6dbdd20aSAndroid Build Coastguard Worker     lines.push_back(std::move(s));
5626*6dbdd20aSAndroid Build Coastguard Worker   }
5627*6dbdd20aSAndroid Build Coastguard Worker   fclose(f);
5628*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(0, remove(temp_file.path.c_str()));
5629*6dbdd20aSAndroid Build Coastguard Worker 
5630*6dbdd20aSAndroid Build Coastguard Worker   // clang-format off
5631*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> golden_lines = {
5632*6dbdd20aSAndroid Build Coastguard Worker       "foo   Instant event\n",
5633*6dbdd20aSAndroid Build Coastguard Worker       "foo   Scoped event {\n",
5634*6dbdd20aSAndroid Build Coastguard Worker       "foo   -  Nested event {\n",
5635*6dbdd20aSAndroid Build Coastguard Worker       "foo   -  -  Instant event\n",
5636*6dbdd20aSAndroid Build Coastguard Worker       "foo   -  -  Annotated event(foo:1, bar:hello)\n",
5637*6dbdd20aSAndroid Build Coastguard Worker       "foo   -  } Nested event\n",
5638*6dbdd20aSAndroid Build Coastguard Worker       "test  AsyncEvent {\n",
5639*6dbdd20aSAndroid Build Coastguard Worker       "foo   EventFromAnotherThread {\n",
5640*6dbdd20aSAndroid Build Coastguard Worker       "foo   -  Instant event\n",
5641*6dbdd20aSAndroid Build Coastguard Worker       "test  } AsyncEvent\n",
5642*6dbdd20aSAndroid Build Coastguard Worker       "foo   } EventFromAnotherThread\n",
5643*6dbdd20aSAndroid Build Coastguard Worker       "foo   -  More annotations(dict:{key:123}, array:[first, second])\n",
5644*6dbdd20aSAndroid Build Coastguard Worker       "foo   } Scoped event\n",
5645*6dbdd20aSAndroid Build Coastguard Worker   };
5646*6dbdd20aSAndroid Build Coastguard Worker   // clang-format on
5647*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(lines, ContainerEq(golden_lines));
5648*6dbdd20aSAndroid Build Coastguard Worker }
5649*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventObserver)5650*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventObserver) {
5651*6dbdd20aSAndroid Build Coastguard Worker   class Observer : public perfetto::TrackEventSessionObserver {
5652*6dbdd20aSAndroid Build Coastguard Worker    public:
5653*6dbdd20aSAndroid Build Coastguard Worker     ~Observer() override = default;
5654*6dbdd20aSAndroid Build Coastguard Worker 
5655*6dbdd20aSAndroid Build Coastguard Worker     void OnSetup(const perfetto::DataSourceBase::SetupArgs&) {
5656*6dbdd20aSAndroid Build Coastguard Worker       // Since other tests here register multiple track event data sources,
5657*6dbdd20aSAndroid Build Coastguard Worker       // ignore all but the first notifications.
5658*6dbdd20aSAndroid Build Coastguard Worker       if (setup_called)
5659*6dbdd20aSAndroid Build Coastguard Worker         return;
5660*6dbdd20aSAndroid Build Coastguard Worker       setup_called = true;
5661*6dbdd20aSAndroid Build Coastguard Worker       if (unsubscribe_at_setup)
5662*6dbdd20aSAndroid Build Coastguard Worker         perfetto::TrackEvent::RemoveSessionObserver(this);
5663*6dbdd20aSAndroid Build Coastguard Worker       // This event isn't recorded in the trace because tracing isn't active yet
5664*6dbdd20aSAndroid Build Coastguard Worker       // when OnSetup is called.
5665*6dbdd20aSAndroid Build Coastguard Worker       TRACE_EVENT_INSTANT("foo", "OnSetup");
5666*6dbdd20aSAndroid Build Coastguard Worker       // However the active tracing categories have already been updated at this
5667*6dbdd20aSAndroid Build Coastguard Worker       // point.
5668*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5669*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5670*6dbdd20aSAndroid Build Coastguard Worker     }
5671*6dbdd20aSAndroid Build Coastguard Worker 
5672*6dbdd20aSAndroid Build Coastguard Worker     void OnStart(const perfetto::DataSourceBase::StartArgs&) {
5673*6dbdd20aSAndroid Build Coastguard Worker       if (start_called)
5674*6dbdd20aSAndroid Build Coastguard Worker         return;
5675*6dbdd20aSAndroid Build Coastguard Worker       start_called = true;
5676*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5677*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5678*6dbdd20aSAndroid Build Coastguard Worker       TRACE_EVENT_INSTANT("foo", "OnStart");
5679*6dbdd20aSAndroid Build Coastguard Worker     }
5680*6dbdd20aSAndroid Build Coastguard Worker 
5681*6dbdd20aSAndroid Build Coastguard Worker     void OnStop(const perfetto::DataSourceBase::StopArgs&) {
5682*6dbdd20aSAndroid Build Coastguard Worker       if (stop_called)
5683*6dbdd20aSAndroid Build Coastguard Worker         return;
5684*6dbdd20aSAndroid Build Coastguard Worker       stop_called = true;
5685*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5686*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5687*6dbdd20aSAndroid Build Coastguard Worker       TRACE_EVENT_INSTANT("foo", "OnStop");
5688*6dbdd20aSAndroid Build Coastguard Worker       perfetto::TrackEvent::Flush();
5689*6dbdd20aSAndroid Build Coastguard Worker     }
5690*6dbdd20aSAndroid Build Coastguard Worker 
5691*6dbdd20aSAndroid Build Coastguard Worker     bool setup_called{};
5692*6dbdd20aSAndroid Build Coastguard Worker     bool start_called{};
5693*6dbdd20aSAndroid Build Coastguard Worker     bool stop_called{};
5694*6dbdd20aSAndroid Build Coastguard Worker     bool unsubscribe_at_setup{};
5695*6dbdd20aSAndroid Build Coastguard Worker   };
5696*6dbdd20aSAndroid Build Coastguard Worker 
5697*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5698*6dbdd20aSAndroid Build Coastguard Worker   {
5699*6dbdd20aSAndroid Build Coastguard Worker     Observer observer;
5700*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::AddSessionObserver(&observer);
5701*6dbdd20aSAndroid Build Coastguard Worker 
5702*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"});
5703*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
5704*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(observer.setup_called);
5705*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(observer.start_called);
5706*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StopBlocking();
5707*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(observer.stop_called);
5708*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::RemoveSessionObserver(&observer);
5709*6dbdd20aSAndroid Build Coastguard Worker     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5710*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(slices, ElementsAre("I:foo.OnStart", "I:foo.OnStop"));
5711*6dbdd20aSAndroid Build Coastguard Worker   }
5712*6dbdd20aSAndroid Build Coastguard Worker 
5713*6dbdd20aSAndroid Build Coastguard Worker   // No notifications after removing observer.
5714*6dbdd20aSAndroid Build Coastguard Worker   {
5715*6dbdd20aSAndroid Build Coastguard Worker     Observer observer;
5716*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::AddSessionObserver(&observer);
5717*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::RemoveSessionObserver(&observer);
5718*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"});
5719*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
5720*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(observer.setup_called);
5721*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(observer.start_called);
5722*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StopBlocking();
5723*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(observer.stop_called);
5724*6dbdd20aSAndroid Build Coastguard Worker   }
5725*6dbdd20aSAndroid Build Coastguard Worker 
5726*6dbdd20aSAndroid Build Coastguard Worker   // Removing observer in a callback.
5727*6dbdd20aSAndroid Build Coastguard Worker   {
5728*6dbdd20aSAndroid Build Coastguard Worker     Observer observer;
5729*6dbdd20aSAndroid Build Coastguard Worker     observer.unsubscribe_at_setup = true;
5730*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::AddSessionObserver(&observer);
5731*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"});
5732*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
5733*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(observer.setup_called);
5734*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(observer.start_called);
5735*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StopBlocking();
5736*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(observer.stop_called);
5737*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::RemoveSessionObserver(&observer);
5738*6dbdd20aSAndroid Build Coastguard Worker   }
5739*6dbdd20aSAndroid Build Coastguard Worker 
5740*6dbdd20aSAndroid Build Coastguard Worker   // Multiple observers.
5741*6dbdd20aSAndroid Build Coastguard Worker   {
5742*6dbdd20aSAndroid Build Coastguard Worker     Observer observer1;
5743*6dbdd20aSAndroid Build Coastguard Worker     Observer observer2;
5744*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::AddSessionObserver(&observer1);
5745*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::AddSessionObserver(&observer2);
5746*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"});
5747*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
5748*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StopBlocking();
5749*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::RemoveSessionObserver(&observer1);
5750*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::RemoveSessionObserver(&observer2);
5751*6dbdd20aSAndroid Build Coastguard Worker     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5752*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(slices, ElementsAre("I:foo.OnStart", "I:foo.OnStart",
5753*6dbdd20aSAndroid Build Coastguard Worker                                     "I:foo.OnStop", "I:foo.OnStop"));
5754*6dbdd20aSAndroid Build Coastguard Worker   }
5755*6dbdd20aSAndroid Build Coastguard Worker 
5756*6dbdd20aSAndroid Build Coastguard Worker   // Multiple observers with one being removed midway.
5757*6dbdd20aSAndroid Build Coastguard Worker   {
5758*6dbdd20aSAndroid Build Coastguard Worker     Observer observer1;
5759*6dbdd20aSAndroid Build Coastguard Worker     Observer observer2;
5760*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::AddSessionObserver(&observer1);
5761*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::AddSessionObserver(&observer2);
5762*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"});
5763*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
5764*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::RemoveSessionObserver(&observer1);
5765*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StopBlocking();
5766*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::RemoveSessionObserver(&observer2);
5767*6dbdd20aSAndroid Build Coastguard Worker     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5768*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(slices,
5769*6dbdd20aSAndroid Build Coastguard Worker                 ElementsAre("I:foo.OnStart", "I:foo.OnStart", "I:foo.OnStop"));
5770*6dbdd20aSAndroid Build Coastguard Worker   }
5771*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5772*6dbdd20aSAndroid Build Coastguard Worker }
5773*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventObserver_ClearIncrementalState)5774*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventObserver_ClearIncrementalState) {
5775*6dbdd20aSAndroid Build Coastguard Worker   class Observer : public perfetto::TrackEventSessionObserver {
5776*6dbdd20aSAndroid Build Coastguard Worker    public:
5777*6dbdd20aSAndroid Build Coastguard Worker     ~Observer() override = default;
5778*6dbdd20aSAndroid Build Coastguard Worker 
5779*6dbdd20aSAndroid Build Coastguard Worker     void OnStart(const perfetto::DataSourceBase::StartArgs&) {
5780*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5781*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5782*6dbdd20aSAndroid Build Coastguard Worker       TRACE_EVENT_INSTANT("foo", "OnStart");
5783*6dbdd20aSAndroid Build Coastguard Worker     }
5784*6dbdd20aSAndroid Build Coastguard Worker 
5785*6dbdd20aSAndroid Build Coastguard Worker     void WillClearIncrementalState(
5786*6dbdd20aSAndroid Build Coastguard Worker         const perfetto::DataSourceBase::ClearIncrementalStateArgs&) {
5787*6dbdd20aSAndroid Build Coastguard Worker       if (clear_incremental_state_called)
5788*6dbdd20aSAndroid Build Coastguard Worker         return;
5789*6dbdd20aSAndroid Build Coastguard Worker       clear_incremental_state_called = true;
5790*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5791*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5792*6dbdd20aSAndroid Build Coastguard Worker       TRACE_EVENT_INSTANT("foo", "WillClearIncrementalState");
5793*6dbdd20aSAndroid Build Coastguard Worker       perfetto::TrackEvent::Flush();
5794*6dbdd20aSAndroid Build Coastguard Worker     }
5795*6dbdd20aSAndroid Build Coastguard Worker 
5796*6dbdd20aSAndroid Build Coastguard Worker     bool clear_incremental_state_called{};
5797*6dbdd20aSAndroid Build Coastguard Worker   };
5798*6dbdd20aSAndroid Build Coastguard Worker 
5799*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5800*6dbdd20aSAndroid Build Coastguard Worker   {
5801*6dbdd20aSAndroid Build Coastguard Worker     Observer observer;
5802*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::AddSessionObserver(&observer);
5803*6dbdd20aSAndroid Build Coastguard Worker 
5804*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TraceConfig cfg;
5805*6dbdd20aSAndroid Build Coastguard Worker     cfg.mutable_incremental_state_config()->set_clear_period_ms(100);
5806*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"}, {}, cfg);
5807*6dbdd20aSAndroid Build Coastguard Worker 
5808*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
5809*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->on_stop.Wait();
5810*6dbdd20aSAndroid Build Coastguard Worker 
5811*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(observer.clear_incremental_state_called);
5812*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::RemoveSessionObserver(&observer);
5813*6dbdd20aSAndroid Build Coastguard Worker     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5814*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(slices, ElementsAre("I:foo.OnStart",
5815*6dbdd20aSAndroid Build Coastguard Worker                                     "I:foo.WillClearIncrementalState"));
5816*6dbdd20aSAndroid Build Coastguard Worker   }
5817*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5818*6dbdd20aSAndroid Build Coastguard Worker }
5819*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventObserver_TwoDataSources)5820*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventObserver_TwoDataSources) {
5821*6dbdd20aSAndroid Build Coastguard Worker   class Observer : public perfetto::TrackEventSessionObserver {
5822*6dbdd20aSAndroid Build Coastguard Worker    public:
5823*6dbdd20aSAndroid Build Coastguard Worker     ~Observer() override = default;
5824*6dbdd20aSAndroid Build Coastguard Worker 
5825*6dbdd20aSAndroid Build Coastguard Worker     void OnStart(const perfetto::DataSourceBase::StartArgs&) {
5826*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(start_called);
5827*6dbdd20aSAndroid Build Coastguard Worker       start_called = true;
5828*6dbdd20aSAndroid Build Coastguard Worker     }
5829*6dbdd20aSAndroid Build Coastguard Worker 
5830*6dbdd20aSAndroid Build Coastguard Worker     bool start_called{};
5831*6dbdd20aSAndroid Build Coastguard Worker   };
5832*6dbdd20aSAndroid Build Coastguard Worker 
5833*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5834*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(tracing_module::IsEnabled());
5835*6dbdd20aSAndroid Build Coastguard Worker 
5836*6dbdd20aSAndroid Build Coastguard Worker   {
5837*6dbdd20aSAndroid Build Coastguard Worker     Observer observer1, observer2;
5838*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::AddSessionObserver(&observer1);
5839*6dbdd20aSAndroid Build Coastguard Worker     tracing_module::AddSessionObserver(&observer2);
5840*6dbdd20aSAndroid Build Coastguard Worker 
5841*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TraceConfig cfg;
5842*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"}, {}, cfg);
5843*6dbdd20aSAndroid Build Coastguard Worker 
5844*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
5845*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->on_stop.Wait();
5846*6dbdd20aSAndroid Build Coastguard Worker 
5847*6dbdd20aSAndroid Build Coastguard Worker     // The tracing_module hasn't registered its data source yet, so observer2
5848*6dbdd20aSAndroid Build Coastguard Worker     // should not be notified.
5849*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(observer1.start_called);
5850*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(observer2.start_called);
5851*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::RemoveSessionObserver(&observer1);
5852*6dbdd20aSAndroid Build Coastguard Worker     tracing_module::RemoveSessionObserver(&observer2);
5853*6dbdd20aSAndroid Build Coastguard Worker   }
5854*6dbdd20aSAndroid Build Coastguard Worker 
5855*6dbdd20aSAndroid Build Coastguard Worker   tracing_module::InitializeCategories();
5856*6dbdd20aSAndroid Build Coastguard Worker 
5857*6dbdd20aSAndroid Build Coastguard Worker   {
5858*6dbdd20aSAndroid Build Coastguard Worker     Observer observer1, observer2;
5859*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::AddSessionObserver(&observer1);
5860*6dbdd20aSAndroid Build Coastguard Worker     tracing_module::AddSessionObserver(&observer2);
5861*6dbdd20aSAndroid Build Coastguard Worker 
5862*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TraceConfig cfg;
5863*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"}, {}, cfg);
5864*6dbdd20aSAndroid Build Coastguard Worker 
5865*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
5866*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->on_stop.Wait();
5867*6dbdd20aSAndroid Build Coastguard Worker 
5868*6dbdd20aSAndroid Build Coastguard Worker     // Each observer should be notified exactly once.
5869*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(observer1.start_called);
5870*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(observer2.start_called);
5871*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::RemoveSessionObserver(&observer1);
5872*6dbdd20aSAndroid Build Coastguard Worker     tracing_module::RemoveSessionObserver(&observer2);
5873*6dbdd20aSAndroid Build Coastguard Worker   }
5874*6dbdd20aSAndroid Build Coastguard Worker 
5875*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5876*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(tracing_module::IsEnabled());
5877*6dbdd20aSAndroid Build Coastguard Worker }
5878*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,TrackEventObserver_AsyncStop)5879*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, TrackEventObserver_AsyncStop) {
5880*6dbdd20aSAndroid Build Coastguard Worker   class Observer : public perfetto::TrackEventSessionObserver {
5881*6dbdd20aSAndroid Build Coastguard Worker    public:
5882*6dbdd20aSAndroid Build Coastguard Worker     ~Observer() override = default;
5883*6dbdd20aSAndroid Build Coastguard Worker 
5884*6dbdd20aSAndroid Build Coastguard Worker     void OnStop(const perfetto::DataSourceBase::StopArgs& args) {
5885*6dbdd20aSAndroid Build Coastguard Worker       async_stop_closure_ = args.HandleStopAsynchronously();
5886*6dbdd20aSAndroid Build Coastguard Worker     }
5887*6dbdd20aSAndroid Build Coastguard Worker 
5888*6dbdd20aSAndroid Build Coastguard Worker     void EmitFinalEvents() {
5889*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(perfetto::TrackEvent::IsEnabled());
5890*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_TRUE(TRACE_EVENT_CATEGORY_ENABLED("foo"));
5891*6dbdd20aSAndroid Build Coastguard Worker       TRACE_EVENT_INSTANT("foo", "FinalEvent");
5892*6dbdd20aSAndroid Build Coastguard Worker       perfetto::TrackEvent::Flush();
5893*6dbdd20aSAndroid Build Coastguard Worker       async_stop_closure_();
5894*6dbdd20aSAndroid Build Coastguard Worker     }
5895*6dbdd20aSAndroid Build Coastguard Worker 
5896*6dbdd20aSAndroid Build Coastguard Worker    private:
5897*6dbdd20aSAndroid Build Coastguard Worker     std::function<void()> async_stop_closure_;
5898*6dbdd20aSAndroid Build Coastguard Worker   };
5899*6dbdd20aSAndroid Build Coastguard Worker 
5900*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5901*6dbdd20aSAndroid Build Coastguard Worker   {
5902*6dbdd20aSAndroid Build Coastguard Worker     Observer observer;
5903*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::AddSessionObserver(&observer);
5904*6dbdd20aSAndroid Build Coastguard Worker 
5905*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"});
5906*6dbdd20aSAndroid Build Coastguard Worker     WaitableTestEvent consumer_stop_signal;
5907*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->SetOnStopCallback(
5908*6dbdd20aSAndroid Build Coastguard Worker         [&consumer_stop_signal] { consumer_stop_signal.Notify(); });
5909*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
5910*6dbdd20aSAndroid Build Coastguard Worker 
5911*6dbdd20aSAndroid Build Coastguard Worker     // Stop and wait for the producer to have seen the stop event.
5912*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->Stop();
5913*6dbdd20aSAndroid Build Coastguard Worker 
5914*6dbdd20aSAndroid Build Coastguard Worker     // At this point tracing should be still allowed because of the
5915*6dbdd20aSAndroid Build Coastguard Worker     // HandleStopAsynchronously() call. This usleep is here just to prevent that
5916*6dbdd20aSAndroid Build Coastguard Worker     // we accidentally pass the test just by virtue of hitting some race. We
5917*6dbdd20aSAndroid Build Coastguard Worker     // should be able to trace up until 5 seconds after seeing the stop when
5918*6dbdd20aSAndroid Build Coastguard Worker     // using the deferred stop mechanism.
5919*6dbdd20aSAndroid Build Coastguard Worker     std::this_thread::sleep_for(std::chrono::milliseconds(250));
5920*6dbdd20aSAndroid Build Coastguard Worker     observer.EmitFinalEvents();
5921*6dbdd20aSAndroid Build Coastguard Worker 
5922*6dbdd20aSAndroid Build Coastguard Worker     // Wait that the stop is propagated to the consumer.
5923*6dbdd20aSAndroid Build Coastguard Worker     consumer_stop_signal.Wait();
5924*6dbdd20aSAndroid Build Coastguard Worker 
5925*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::RemoveSessionObserver(&observer);
5926*6dbdd20aSAndroid Build Coastguard Worker     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
5927*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(slices, ElementsAre("I:foo.FinalEvent"));
5928*6dbdd20aSAndroid Build Coastguard Worker   }
5929*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::TrackEvent::IsEnabled());
5930*6dbdd20aSAndroid Build Coastguard Worker }
5931*6dbdd20aSAndroid Build Coastguard Worker 
5932*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_CLANG)
5933*6dbdd20aSAndroid Build Coastguard Worker struct __attribute__((capability("mutex"))) MockMutex {
Lock__anonfc73210d0111::MockMutex5934*6dbdd20aSAndroid Build Coastguard Worker   void Lock() __attribute__((acquire_capability())) {}
Unlock__anonfc73210d0111::MockMutex5935*6dbdd20aSAndroid Build Coastguard Worker   void Unlock() __attribute__((release_capability())) {}
5936*6dbdd20aSAndroid Build Coastguard Worker };
5937*6dbdd20aSAndroid Build Coastguard Worker 
5938*6dbdd20aSAndroid Build Coastguard Worker struct AnnotatedObject {
5939*6dbdd20aSAndroid Build Coastguard Worker   MockMutex mutex;
5940*6dbdd20aSAndroid Build Coastguard Worker   int value __attribute__((guarded_by(mutex))) = {};
5941*6dbdd20aSAndroid Build Coastguard Worker };
5942*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ThreadSafetyAnnotation)5943*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ThreadSafetyAnnotation) {
5944*6dbdd20aSAndroid Build Coastguard Worker   AnnotatedObject obj;
5945*6dbdd20aSAndroid Build Coastguard Worker 
5946*6dbdd20aSAndroid Build Coastguard Worker   // Access to the locked field is only allowed while holding the mutex.
5947*6dbdd20aSAndroid Build Coastguard Worker   obj.mutex.Lock();
5948*6dbdd20aSAndroid Build Coastguard Worker   obj.value = 1;
5949*6dbdd20aSAndroid Build Coastguard Worker   obj.mutex.Unlock();
5950*6dbdd20aSAndroid Build Coastguard Worker 
5951*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
5952*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5953*6dbdd20aSAndroid Build Coastguard Worker 
5954*6dbdd20aSAndroid Build Coastguard Worker   // It should be possible to trace the field while holding the lock.
5955*6dbdd20aSAndroid Build Coastguard Worker   obj.mutex.Lock();
5956*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT("cat", "Instant", "value", obj.value);
5957*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_INSTANT1("cat", "InstantLegacy", 0, "value", obj.value);
5958*6dbdd20aSAndroid Build Coastguard Worker   { TRACE_EVENT("cat", "Scoped", "value", obj.value); }
5959*6dbdd20aSAndroid Build Coastguard Worker   { TRACE_EVENT1("cat", "ScopedLegacy", "value", obj.value); }
5960*6dbdd20aSAndroid Build Coastguard Worker   obj.mutex.Unlock();
5961*6dbdd20aSAndroid Build Coastguard Worker 
5962*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
5963*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("I:cat.Instant(value=(int)1)",
5964*6dbdd20aSAndroid Build Coastguard Worker                                   "[track=0]I:cat.InstantLegacy(value=(int)1)",
5965*6dbdd20aSAndroid Build Coastguard Worker                                   "B:cat.Scoped(value=(int)1)", "E",
5966*6dbdd20aSAndroid Build Coastguard Worker                                   "B:cat.ScopedLegacy(value=(int)1)", "E"));
5967*6dbdd20aSAndroid Build Coastguard Worker }
5968*6dbdd20aSAndroid Build Coastguard Worker #endif  // PERFETTO_BUILDFLAG(PERFETTO_COMPILER_CLANG)
5969*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,CountersDeltaEncoding)5970*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, CountersDeltaEncoding) {
5971*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
5972*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
5973*6dbdd20aSAndroid Build Coastguard Worker 
5974*6dbdd20aSAndroid Build Coastguard Worker   // Describe a counter track.
5975*6dbdd20aSAndroid Build Coastguard Worker   perfetto::CounterTrack track1 =
5976*6dbdd20aSAndroid Build Coastguard Worker       perfetto::CounterTrack("Framerate1", "fps1").set_is_incremental(true);
5977*6dbdd20aSAndroid Build Coastguard Worker   // Global tracks can be constructed at build time.
5978*6dbdd20aSAndroid Build Coastguard Worker   constexpr perfetto::CounterTrack track2 =
5979*6dbdd20aSAndroid Build Coastguard Worker       perfetto::CounterTrack::Global("Framerate2", "fps2")
5980*6dbdd20aSAndroid Build Coastguard Worker           .set_is_incremental(true);
5981*6dbdd20aSAndroid Build Coastguard Worker   perfetto::CounterTrack track3 = perfetto::CounterTrack("Framerate3", "fps3");
5982*6dbdd20aSAndroid Build Coastguard Worker 
5983*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track1, 120);
5984*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track2, 1000);
5985*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track3, 10009);
5986*6dbdd20aSAndroid Build Coastguard Worker 
5987*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track1, 10);
5988*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track1, 1200);
5989*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track1, 34);
5990*6dbdd20aSAndroid Build Coastguard Worker 
5991*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track3, 975);
5992*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track2, 449);
5993*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track2, 2);
5994*6dbdd20aSAndroid Build Coastguard Worker 
5995*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track3, 1091);
5996*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track3, 110);
5997*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track3, 1081);
5998*6dbdd20aSAndroid Build Coastguard Worker 
5999*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track1, 98);
6000*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", track2, 1084);
6001*6dbdd20aSAndroid Build Coastguard Worker 
6002*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
6003*6dbdd20aSAndroid Build Coastguard Worker   std::unordered_map<uint64_t, std::string> counter_names;
6004*6dbdd20aSAndroid Build Coastguard Worker   // Map(Counter name -> counter values)
6005*6dbdd20aSAndroid Build Coastguard Worker   std::unordered_map<std::string, std::vector<int64_t>> values;
6006*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
6007*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_descriptor()) {
6008*6dbdd20aSAndroid Build Coastguard Worker       auto& desc = packet.track_descriptor();
6009*6dbdd20aSAndroid Build Coastguard Worker       if (!desc.has_counter())
6010*6dbdd20aSAndroid Build Coastguard Worker         continue;
6011*6dbdd20aSAndroid Build Coastguard Worker       counter_names[desc.uuid()] =
6012*6dbdd20aSAndroid Build Coastguard Worker           desc.has_name() ? desc.name() : desc.static_name();
6013*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ((desc.static_name() != "Framerate3"),
6014*6dbdd20aSAndroid Build Coastguard Worker                 desc.counter().is_incremental());
6015*6dbdd20aSAndroid Build Coastguard Worker     }
6016*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_event()) {
6017*6dbdd20aSAndroid Build Coastguard Worker       auto event = packet.track_event();
6018*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(perfetto::protos::gen::TrackEvent_Type_TYPE_COUNTER,
6019*6dbdd20aSAndroid Build Coastguard Worker                 event.type());
6020*6dbdd20aSAndroid Build Coastguard Worker       auto& counter_name = counter_names.at(event.track_uuid());
6021*6dbdd20aSAndroid Build Coastguard Worker       values[counter_name].push_back(event.counter_value());
6022*6dbdd20aSAndroid Build Coastguard Worker     }
6023*6dbdd20aSAndroid Build Coastguard Worker   }
6024*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_EQ(3u, values.size());
6025*6dbdd20aSAndroid Build Coastguard Worker   using IntVector = std::vector<int64_t>;
6026*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ((IntVector{120, -110, 1190, -1166, 64}), values.at("Framerate1"));
6027*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ((IntVector{1000, -551, -447, 1082}), values.at("Framerate2"));
6028*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ((IntVector{10009, 975, 1091, 110, 1081}), values.at("Framerate3"));
6029*6dbdd20aSAndroid Build Coastguard Worker }
6030*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,Counters)6031*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, Counters) {
6032*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
6033*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6034*6dbdd20aSAndroid Build Coastguard Worker 
6035*6dbdd20aSAndroid Build Coastguard Worker   // Describe a counter track.
6036*6dbdd20aSAndroid Build Coastguard Worker   perfetto::CounterTrack fps_track = perfetto::CounterTrack("Framerate", "fps");
6037*6dbdd20aSAndroid Build Coastguard Worker 
6038*6dbdd20aSAndroid Build Coastguard Worker   // Emit an integer sample.
6039*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", fps_track, 120);
6040*6dbdd20aSAndroid Build Coastguard Worker 
6041*6dbdd20aSAndroid Build Coastguard Worker   // Global tracks can be constructed at build time.
6042*6dbdd20aSAndroid Build Coastguard Worker   constexpr auto goats_track =
6043*6dbdd20aSAndroid Build Coastguard Worker       perfetto::CounterTrack::Global("Goats teleported", "goats x 1000")
6044*6dbdd20aSAndroid Build Coastguard Worker           .set_unit_multiplier(1000);
6045*6dbdd20aSAndroid Build Coastguard Worker   static_assert(goats_track.uuid == 0x6072fc234f82df11,
6046*6dbdd20aSAndroid Build Coastguard Worker                 "Counter track uuid mismatch");
6047*6dbdd20aSAndroid Build Coastguard Worker 
6048*6dbdd20aSAndroid Build Coastguard Worker   // Emit some floating point samples.
6049*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", goats_track, 0.25);
6050*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", goats_track, 0.5);
6051*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", goats_track, 0.75);
6052*6dbdd20aSAndroid Build Coastguard Worker 
6053*6dbdd20aSAndroid Build Coastguard Worker   // Emit a sample using an inline track name.
6054*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat", "Voltage", 220);
6055*6dbdd20aSAndroid Build Coastguard Worker 
6056*6dbdd20aSAndroid Build Coastguard Worker   // Emit sample with a custom timestamp.
6057*6dbdd20aSAndroid Build Coastguard Worker   TRACE_COUNTER("cat",
6058*6dbdd20aSAndroid Build Coastguard Worker                 perfetto::CounterTrack("Power", "GW").set_category("dmc"),
6059*6dbdd20aSAndroid Build Coastguard Worker                 MyTimestamp(1985u), 1.21f);
6060*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
6061*6dbdd20aSAndroid Build Coastguard Worker   std::map<uint64_t, std::string> counter_names;
6062*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> counter_samples;
6063*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : trace.packet()) {
6064*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_event()) {
6065*6dbdd20aSAndroid Build Coastguard Worker       auto event = packet.track_event();
6066*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(perfetto::protos::gen::TrackEvent_Type_TYPE_COUNTER,
6067*6dbdd20aSAndroid Build Coastguard Worker                 event.type());
6068*6dbdd20aSAndroid Build Coastguard Worker       std::stringstream sample;
6069*6dbdd20aSAndroid Build Coastguard Worker       std::string counter_name = counter_names[event.track_uuid()];
6070*6dbdd20aSAndroid Build Coastguard Worker       sample << counter_name << " = ";
6071*6dbdd20aSAndroid Build Coastguard Worker       if (event.has_counter_value()) {
6072*6dbdd20aSAndroid Build Coastguard Worker         sample << event.counter_value();
6073*6dbdd20aSAndroid Build Coastguard Worker       } else if (event.has_double_counter_value()) {
6074*6dbdd20aSAndroid Build Coastguard Worker         sample << event.double_counter_value();
6075*6dbdd20aSAndroid Build Coastguard Worker       }
6076*6dbdd20aSAndroid Build Coastguard Worker       if (counter_name == "Power") {
6077*6dbdd20aSAndroid Build Coastguard Worker         EXPECT_EQ(1985u, packet.timestamp());
6078*6dbdd20aSAndroid Build Coastguard Worker       }
6079*6dbdd20aSAndroid Build Coastguard Worker       counter_samples.push_back(sample.str());
6080*6dbdd20aSAndroid Build Coastguard Worker     }
6081*6dbdd20aSAndroid Build Coastguard Worker 
6082*6dbdd20aSAndroid Build Coastguard Worker     if (!packet.has_track_descriptor() ||
6083*6dbdd20aSAndroid Build Coastguard Worker         !packet.track_descriptor().has_counter()) {
6084*6dbdd20aSAndroid Build Coastguard Worker       continue;
6085*6dbdd20aSAndroid Build Coastguard Worker     }
6086*6dbdd20aSAndroid Build Coastguard Worker     auto desc = packet.track_descriptor();
6087*6dbdd20aSAndroid Build Coastguard Worker     counter_names[desc.uuid()] =
6088*6dbdd20aSAndroid Build Coastguard Worker         desc.has_name() ? desc.name() : desc.static_name();
6089*6dbdd20aSAndroid Build Coastguard Worker     if (desc.name() == "Framerate") {
6090*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("fps", desc.counter().unit_name());
6091*6dbdd20aSAndroid Build Coastguard Worker     } else if (desc.name() == "Goats teleported") {
6092*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("goats x 1000", desc.counter().unit_name());
6093*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(1000, desc.counter().unit_multiplier());
6094*6dbdd20aSAndroid Build Coastguard Worker     } else if (desc.name() == "Power") {
6095*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("GW", desc.counter().unit_name());
6096*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("dmc", desc.counter().categories()[0]);
6097*6dbdd20aSAndroid Build Coastguard Worker     }
6098*6dbdd20aSAndroid Build Coastguard Worker   }
6099*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(4u, counter_names.size());
6100*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(counter_samples,
6101*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("Framerate = 120", "Goats teleported = 0.25",
6102*6dbdd20aSAndroid Build Coastguard Worker                           "Goats teleported = 0.5", "Goats teleported = 0.75",
6103*6dbdd20aSAndroid Build Coastguard Worker                           "Voltage = 220", "Power = 1.21"));
6104*6dbdd20aSAndroid Build Coastguard Worker }
6105*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ScrapingTrackEventBegin)6106*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ScrapingTrackEventBegin) {
6107*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6108*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6109*6dbdd20aSAndroid Build Coastguard Worker 
6110*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "MainEvent");
6111*6dbdd20aSAndroid Build Coastguard Worker 
6112*6dbdd20aSAndroid Build Coastguard Worker   // Stop tracing but don't flush. Rely on scraping to get the chunk contents.
6113*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
6114*6dbdd20aSAndroid Build Coastguard Worker 
6115*6dbdd20aSAndroid Build Coastguard Worker   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
6116*6dbdd20aSAndroid Build Coastguard Worker 
6117*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
6118*6dbdd20aSAndroid Build Coastguard Worker }
6119*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ScrapingTrackEventEnd)6120*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ScrapingTrackEventEnd) {
6121*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6122*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6123*6dbdd20aSAndroid Build Coastguard Worker 
6124*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "MainEvent");
6125*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("test");
6126*6dbdd20aSAndroid Build Coastguard Worker 
6127*6dbdd20aSAndroid Build Coastguard Worker   // Stop tracing but don't flush. Rely on scraping to get the chunk contents.
6128*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
6129*6dbdd20aSAndroid Build Coastguard Worker 
6130*6dbdd20aSAndroid Build Coastguard Worker   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
6131*6dbdd20aSAndroid Build Coastguard Worker 
6132*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent", "E"));
6133*6dbdd20aSAndroid Build Coastguard Worker }
6134*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,EmptyEvent)6135*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, EmptyEvent) {
6136*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6137*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6138*6dbdd20aSAndroid Build Coastguard Worker 
6139*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "MainEvent");
6140*6dbdd20aSAndroid Build Coastguard Worker 
6141*6dbdd20aSAndroid Build Coastguard Worker   // An empty event will allow the previous track packet to be scraped.
6142*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_INTERNAL_ADD_EMPTY_EVENT();
6143*6dbdd20aSAndroid Build Coastguard Worker 
6144*6dbdd20aSAndroid Build Coastguard Worker   // Stop tracing but don't flush. Rely on scraping to get the chunk contents.
6145*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
6146*6dbdd20aSAndroid Build Coastguard Worker 
6147*6dbdd20aSAndroid Build Coastguard Worker   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
6148*6dbdd20aSAndroid Build Coastguard Worker 
6149*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
6150*6dbdd20aSAndroid Build Coastguard Worker }
6151*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ConsecutiveEmptyEventsSkipped)6152*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ConsecutiveEmptyEventsSkipped) {
6153*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6154*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6155*6dbdd20aSAndroid Build Coastguard Worker 
6156*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "MainEvent");
6157*6dbdd20aSAndroid Build Coastguard Worker 
6158*6dbdd20aSAndroid Build Coastguard Worker   // Emit many empty events that wouldn't fit into one chunk.
6159*6dbdd20aSAndroid Build Coastguard Worker   constexpr int kNumEvents = 10000;
6160*6dbdd20aSAndroid Build Coastguard Worker   for (int i = 0; i < kNumEvents; ++i) {
6161*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_INTERNAL_ADD_EMPTY_EVENT();
6162*6dbdd20aSAndroid Build Coastguard Worker   }
6163*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
6164*6dbdd20aSAndroid Build Coastguard Worker   auto it = std::find_if(trace.packet().begin(), trace.packet().end(),
6165*6dbdd20aSAndroid Build Coastguard Worker                          [](const perfetto::protos::gen::TracePacket& packet) {
6166*6dbdd20aSAndroid Build Coastguard Worker                            return packet.has_trace_stats();
6167*6dbdd20aSAndroid Build Coastguard Worker                          });
6168*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_NE(it, trace.packet().end());
6169*6dbdd20aSAndroid Build Coastguard Worker   // Extra empty events should be skipped so only one chunk should be allocated.
6170*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(it->trace_stats().buffer_stats()[0].chunks_read(), 1u);
6171*6dbdd20aSAndroid Build Coastguard Worker }
6172*6dbdd20aSAndroid Build Coastguard Worker 
6173*6dbdd20aSAndroid Build Coastguard Worker // Make sure that we set correct track_uuid for legacy events
6174*6dbdd20aSAndroid Build Coastguard Worker // of type TrackEvent::TYPE_UNSPECIFIED.
6175*6dbdd20aSAndroid Build Coastguard Worker // For such events we set fields of `track_event.legacy_event` and
6176*6dbdd20aSAndroid Build Coastguard Worker // we set `track_event.track_uuid` to zero to dissociate it with
6177*6dbdd20aSAndroid Build Coastguard Worker // default track.
TEST_P(PerfettoApiTest,CorrectTrackUUIDForLegacyEvents)6178*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, CorrectTrackUUIDForLegacyEvents) {
6179*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"cat"});
6180*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6181*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cat", "foo",
6182*6dbdd20aSAndroid Build Coastguard Worker                                     TRACE_ID_WITH_SCOPE("foo", 1));
6183*6dbdd20aSAndroid Build Coastguard Worker 
6184*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6185*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices,
6186*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("[track=0]Legacy_b(unscoped_id=11250026935264495724)("
6187*6dbdd20aSAndroid Build Coastguard Worker                           "id_scope=\"foo\"):cat.foo"));
6188*6dbdd20aSAndroid Build Coastguard Worker }
6189*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,ActivateTriggers)6190*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, ActivateTriggers) {
6191*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6192*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
6193*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig::TriggerConfig* tr_cfg = cfg.mutable_trigger_config();
6194*6dbdd20aSAndroid Build Coastguard Worker   tr_cfg->set_trigger_mode(perfetto::TraceConfig::TriggerConfig::STOP_TRACING);
6195*6dbdd20aSAndroid Build Coastguard Worker   tr_cfg->set_trigger_timeout_ms(5000);
6196*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig::TriggerConfig::Trigger* trigger =
6197*6dbdd20aSAndroid Build Coastguard Worker       tr_cfg->add_triggers();
6198*6dbdd20aSAndroid Build Coastguard Worker   trigger->set_name("trigger1");
6199*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
6200*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6201*6dbdd20aSAndroid Build Coastguard Worker 
6202*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::ActivateTriggers({"trigger2", "trigger1"}, 10000);
6203*6dbdd20aSAndroid Build Coastguard Worker 
6204*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->on_stop.Wait();
6205*6dbdd20aSAndroid Build Coastguard Worker 
6206*6dbdd20aSAndroid Build Coastguard Worker   std::vector<char> bytes = tracing_session->get()->ReadTraceBlocking();
6207*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace parsed_trace;
6208*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(parsed_trace.ParseFromArray(bytes.data(), bytes.size()));
6209*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(
6210*6dbdd20aSAndroid Build Coastguard Worker       parsed_trace,
6211*6dbdd20aSAndroid Build Coastguard Worker       Property(&perfetto::protos::gen::Trace::packet,
6212*6dbdd20aSAndroid Build Coastguard Worker                Contains(Property(
6213*6dbdd20aSAndroid Build Coastguard Worker                    &perfetto::protos::gen::TracePacket::trigger,
6214*6dbdd20aSAndroid Build Coastguard Worker                    Property(&perfetto::protos::gen::Trigger::trigger_name,
6215*6dbdd20aSAndroid Build Coastguard Worker                             "trigger1")))));
6216*6dbdd20aSAndroid Build Coastguard Worker }
6217*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,StartTracingWhileExecutingTracepoint)6218*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, StartTracingWhileExecutingTracepoint) {
6219*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6220*6dbdd20aSAndroid Build Coastguard Worker   auto* buffer = cfg.add_buffers();
6221*6dbdd20aSAndroid Build Coastguard Worker   buffer->set_size_kb(64);
6222*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6223*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
6224*6dbdd20aSAndroid Build Coastguard Worker 
6225*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<bool> quit{false};
6226*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent outside_tracing;
6227*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent tracing;
6228*6dbdd20aSAndroid Build Coastguard Worker   std::thread t([&] {
6229*6dbdd20aSAndroid Build Coastguard Worker     while (!quit) {
6230*6dbdd20aSAndroid Build Coastguard Worker       MockDataSource::Trace([&](MockDataSource::TraceContext ctx) {
6231*6dbdd20aSAndroid Build Coastguard Worker         {
6232*6dbdd20aSAndroid Build Coastguard Worker           auto packet = ctx.NewTracePacket();
6233*6dbdd20aSAndroid Build Coastguard Worker           packet->set_for_testing()->set_str("My String");
6234*6dbdd20aSAndroid Build Coastguard Worker         }
6235*6dbdd20aSAndroid Build Coastguard Worker         { auto packet = ctx.NewTracePacket(); }
6236*6dbdd20aSAndroid Build Coastguard Worker         tracing.Notify();
6237*6dbdd20aSAndroid Build Coastguard Worker       });
6238*6dbdd20aSAndroid Build Coastguard Worker       outside_tracing.Notify();
6239*6dbdd20aSAndroid Build Coastguard Worker       std::this_thread::yield();
6240*6dbdd20aSAndroid Build Coastguard Worker     }
6241*6dbdd20aSAndroid Build Coastguard Worker   });
6242*6dbdd20aSAndroid Build Coastguard Worker   outside_tracing.Wait();
6243*6dbdd20aSAndroid Build Coastguard Worker 
6244*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
6245*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6246*6dbdd20aSAndroid Build Coastguard Worker   tracing.Wait();
6247*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
6248*6dbdd20aSAndroid Build Coastguard Worker 
6249*6dbdd20aSAndroid Build Coastguard Worker   // The data source instance should be stopped.
6250*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
6251*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop.Wait();
6252*6dbdd20aSAndroid Build Coastguard Worker 
6253*6dbdd20aSAndroid Build Coastguard Worker   quit = true;
6254*6dbdd20aSAndroid Build Coastguard Worker   t.join();
6255*6dbdd20aSAndroid Build Coastguard Worker 
6256*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
6257*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> test_strings;
6258*6dbdd20aSAndroid Build Coastguard Worker   for (auto& trace_packet : trace.packet()) {
6259*6dbdd20aSAndroid Build Coastguard Worker     if (trace_packet.has_for_testing()) {
6260*6dbdd20aSAndroid Build Coastguard Worker       test_strings.push_back(trace_packet.for_testing().str());
6261*6dbdd20aSAndroid Build Coastguard Worker     }
6262*6dbdd20aSAndroid Build Coastguard Worker   }
6263*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(test_strings, AllOf(Not(IsEmpty()), Each("My String")));
6264*6dbdd20aSAndroid Build Coastguard Worker }
6265*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,SystemDisconnect)6266*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, SystemDisconnect) {
6267*6dbdd20aSAndroid Build Coastguard Worker   if (GetParam() != perfetto::kSystemBackend) {
6268*6dbdd20aSAndroid Build Coastguard Worker     GTEST_SKIP();
6269*6dbdd20aSAndroid Build Coastguard Worker   }
6270*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
6271*6dbdd20aSAndroid Build Coastguard Worker   data_source->handle_stop_asynchronously = true;
6272*6dbdd20aSAndroid Build Coastguard Worker 
6273*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6274*6dbdd20aSAndroid Build Coastguard Worker   auto* buffer = cfg.add_buffers();
6275*6dbdd20aSAndroid Build Coastguard Worker   buffer->set_size_kb(64);
6276*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6277*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
6278*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
6279*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6280*6dbdd20aSAndroid Build Coastguard Worker 
6281*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<bool> quit1{false};
6282*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent tracing1;
6283*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<bool> quit2{false};
6284*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent tracing2;
6285*6dbdd20aSAndroid Build Coastguard Worker   std::thread t([&] {
6286*6dbdd20aSAndroid Build Coastguard Worker     while (!quit1) {
6287*6dbdd20aSAndroid Build Coastguard Worker       MockDataSource::Trace(
6288*6dbdd20aSAndroid Build Coastguard Worker           [&](MockDataSource::TraceContext) { tracing1.Notify(); });
6289*6dbdd20aSAndroid Build Coastguard Worker       std::this_thread::yield();
6290*6dbdd20aSAndroid Build Coastguard Worker     }
6291*6dbdd20aSAndroid Build Coastguard Worker     while (!quit2) {
6292*6dbdd20aSAndroid Build Coastguard Worker       MockDataSource::Trace([&](MockDataSource::TraceContext ctx) {
6293*6dbdd20aSAndroid Build Coastguard Worker         {
6294*6dbdd20aSAndroid Build Coastguard Worker           auto packet = ctx.NewTracePacket();
6295*6dbdd20aSAndroid Build Coastguard Worker           packet->set_for_testing()->set_str("New session");
6296*6dbdd20aSAndroid Build Coastguard Worker         }
6297*6dbdd20aSAndroid Build Coastguard Worker         { auto packet = ctx.NewTracePacket(); }
6298*6dbdd20aSAndroid Build Coastguard Worker         tracing2.Notify();
6299*6dbdd20aSAndroid Build Coastguard Worker       });
6300*6dbdd20aSAndroid Build Coastguard Worker       std::this_thread::yield();
6301*6dbdd20aSAndroid Build Coastguard Worker     }
6302*6dbdd20aSAndroid Build Coastguard Worker   });
6303*6dbdd20aSAndroid Build Coastguard Worker   auto cleanup = MakeCleanup([&] {
6304*6dbdd20aSAndroid Build Coastguard Worker     if (t.joinable()) {
6305*6dbdd20aSAndroid Build Coastguard Worker       quit1 = true;
6306*6dbdd20aSAndroid Build Coastguard Worker       quit2 = true;
6307*6dbdd20aSAndroid Build Coastguard Worker       t.join();
6308*6dbdd20aSAndroid Build Coastguard Worker     }
6309*6dbdd20aSAndroid Build Coastguard Worker   });
6310*6dbdd20aSAndroid Build Coastguard Worker   tracing1.Wait();
6311*6dbdd20aSAndroid Build Coastguard Worker 
6312*6dbdd20aSAndroid Build Coastguard Worker   // Restarts the system service. This will cause the producer and consumer to
6313*6dbdd20aSAndroid Build Coastguard Worker   // disconnect.
6314*6dbdd20aSAndroid Build Coastguard Worker   system_service_.Restart();
6315*6dbdd20aSAndroid Build Coastguard Worker 
6316*6dbdd20aSAndroid Build Coastguard Worker   // The data source instance should be stopped.
6317*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop.Wait();
6318*6dbdd20aSAndroid Build Coastguard Worker 
6319*6dbdd20aSAndroid Build Coastguard Worker   // The stop is not finalized yet. Test that creating a new trace writer
6320*6dbdd20aSAndroid Build Coastguard Worker   // doesn't cause any problem.
6321*6dbdd20aSAndroid Build Coastguard Worker   MockDataSource::Trace([&](MockDataSource::TraceContext ctx) {
6322*6dbdd20aSAndroid Build Coastguard Worker     {
6323*6dbdd20aSAndroid Build Coastguard Worker       auto packet = ctx.NewTracePacket();
6324*6dbdd20aSAndroid Build Coastguard Worker       packet->set_for_testing()->set_str("Content");
6325*6dbdd20aSAndroid Build Coastguard Worker     }
6326*6dbdd20aSAndroid Build Coastguard Worker     { auto packet = ctx.NewTracePacket(); }
6327*6dbdd20aSAndroid Build Coastguard Worker   });
6328*6dbdd20aSAndroid Build Coastguard Worker 
6329*6dbdd20aSAndroid Build Coastguard Worker   data_source->async_stop_closure();
6330*6dbdd20aSAndroid Build Coastguard Worker 
6331*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->on_stop.Wait();
6332*6dbdd20aSAndroid Build Coastguard Worker 
6333*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<perfetto::TracingSession> new_session =
6334*6dbdd20aSAndroid Build Coastguard Worker       perfetto::Tracing::NewTrace(/*backend=*/GetParam());
6335*6dbdd20aSAndroid Build Coastguard Worker   // Wait for reconnection
6336*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(WaitForOneProducerConnected(new_session.get()));
6337*6dbdd20aSAndroid Build Coastguard Worker 
6338*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session2 = NewTrace(cfg);
6339*6dbdd20aSAndroid Build Coastguard Worker   tracing_session2->get()->StartBlocking();
6340*6dbdd20aSAndroid Build Coastguard Worker 
6341*6dbdd20aSAndroid Build Coastguard Worker   quit1 = true;
6342*6dbdd20aSAndroid Build Coastguard Worker   tracing2.Wait();
6343*6dbdd20aSAndroid Build Coastguard Worker   quit2 = true;
6344*6dbdd20aSAndroid Build Coastguard Worker   t.join();
6345*6dbdd20aSAndroid Build Coastguard Worker 
6346*6dbdd20aSAndroid Build Coastguard Worker   data_source->handle_stop_asynchronously = false;
6347*6dbdd20aSAndroid Build Coastguard Worker 
6348*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session2);
6349*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> test_strings;
6350*6dbdd20aSAndroid Build Coastguard Worker   for (auto& trace_packet : trace.packet()) {
6351*6dbdd20aSAndroid Build Coastguard Worker     if (trace_packet.has_for_testing()) {
6352*6dbdd20aSAndroid Build Coastguard Worker       test_strings.push_back(trace_packet.for_testing().str());
6353*6dbdd20aSAndroid Build Coastguard Worker     }
6354*6dbdd20aSAndroid Build Coastguard Worker   }
6355*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(test_strings, AllOf(Not(IsEmpty()), Each("New session")));
6356*6dbdd20aSAndroid Build Coastguard Worker }
6357*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,SystemDisconnectAsyncOnStopNoTracing)6358*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, SystemDisconnectAsyncOnStopNoTracing) {
6359*6dbdd20aSAndroid Build Coastguard Worker   if (GetParam() != perfetto::kSystemBackend) {
6360*6dbdd20aSAndroid Build Coastguard Worker     GTEST_SKIP();
6361*6dbdd20aSAndroid Build Coastguard Worker   }
6362*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
6363*6dbdd20aSAndroid Build Coastguard Worker   data_source->handle_stop_asynchronously = true;
6364*6dbdd20aSAndroid Build Coastguard Worker 
6365*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6366*6dbdd20aSAndroid Build Coastguard Worker   auto* buffer = cfg.add_buffers();
6367*6dbdd20aSAndroid Build Coastguard Worker   buffer->set_size_kb(64);
6368*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6369*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
6370*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
6371*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6372*6dbdd20aSAndroid Build Coastguard Worker 
6373*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<bool> quit1{false};
6374*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent tracing1;
6375*6dbdd20aSAndroid Build Coastguard Worker   std::thread t([&] {
6376*6dbdd20aSAndroid Build Coastguard Worker     while (!quit1) {
6377*6dbdd20aSAndroid Build Coastguard Worker       MockDataSource::Trace(
6378*6dbdd20aSAndroid Build Coastguard Worker           [&](MockDataSource::TraceContext) { tracing1.Notify(); });
6379*6dbdd20aSAndroid Build Coastguard Worker       std::this_thread::yield();
6380*6dbdd20aSAndroid Build Coastguard Worker     }
6381*6dbdd20aSAndroid Build Coastguard Worker   });
6382*6dbdd20aSAndroid Build Coastguard Worker   auto cleanup = MakeCleanup([&] {
6383*6dbdd20aSAndroid Build Coastguard Worker     if (t.joinable()) {
6384*6dbdd20aSAndroid Build Coastguard Worker       quit1 = true;
6385*6dbdd20aSAndroid Build Coastguard Worker       t.join();
6386*6dbdd20aSAndroid Build Coastguard Worker     }
6387*6dbdd20aSAndroid Build Coastguard Worker   });
6388*6dbdd20aSAndroid Build Coastguard Worker   tracing1.Wait();
6389*6dbdd20aSAndroid Build Coastguard Worker 
6390*6dbdd20aSAndroid Build Coastguard Worker   // Restarts the system service. This will cause the producer and consumer to
6391*6dbdd20aSAndroid Build Coastguard Worker   // disconnect.
6392*6dbdd20aSAndroid Build Coastguard Worker   system_service_.Restart();
6393*6dbdd20aSAndroid Build Coastguard Worker 
6394*6dbdd20aSAndroid Build Coastguard Worker   // The data source instance should be stopped. Don't acknowledge the stop yet.
6395*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop.Wait();
6396*6dbdd20aSAndroid Build Coastguard Worker 
6397*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->on_stop.Wait();
6398*6dbdd20aSAndroid Build Coastguard Worker 
6399*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<perfetto::TracingSession> new_session =
6400*6dbdd20aSAndroid Build Coastguard Worker       perfetto::Tracing::NewTrace(/*backend=*/GetParam());
6401*6dbdd20aSAndroid Build Coastguard Worker   // Wait for reconnection
6402*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(WaitForOneProducerConnected(new_session.get()));
6403*6dbdd20aSAndroid Build Coastguard Worker 
6404*6dbdd20aSAndroid Build Coastguard Worker   data_source->async_stop_closure();
6405*6dbdd20aSAndroid Build Coastguard Worker 
6406*6dbdd20aSAndroid Build Coastguard Worker   data_source->handle_stop_asynchronously = false;
6407*6dbdd20aSAndroid Build Coastguard Worker }
6408*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,SystemDisconnectAsyncOnStopRestartTracing)6409*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, SystemDisconnectAsyncOnStopRestartTracing) {
6410*6dbdd20aSAndroid Build Coastguard Worker   if (GetParam() != perfetto::kSystemBackend) {
6411*6dbdd20aSAndroid Build Coastguard Worker     GTEST_SKIP();
6412*6dbdd20aSAndroid Build Coastguard Worker   }
6413*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
6414*6dbdd20aSAndroid Build Coastguard Worker   data_source->handle_stop_asynchronously = true;
6415*6dbdd20aSAndroid Build Coastguard Worker 
6416*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6417*6dbdd20aSAndroid Build Coastguard Worker   auto* buffer = cfg.add_buffers();
6418*6dbdd20aSAndroid Build Coastguard Worker   buffer->set_size_kb(64);
6419*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6420*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
6421*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
6422*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6423*6dbdd20aSAndroid Build Coastguard Worker 
6424*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<bool> quit1{false};
6425*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent tracing1;
6426*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<bool> quit2{false};
6427*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent tracing2;
6428*6dbdd20aSAndroid Build Coastguard Worker   std::thread t([&] {
6429*6dbdd20aSAndroid Build Coastguard Worker     while (!quit1) {
6430*6dbdd20aSAndroid Build Coastguard Worker       MockDataSource::Trace(
6431*6dbdd20aSAndroid Build Coastguard Worker           [&](MockDataSource::TraceContext) { tracing1.Notify(); });
6432*6dbdd20aSAndroid Build Coastguard Worker       std::this_thread::yield();
6433*6dbdd20aSAndroid Build Coastguard Worker     }
6434*6dbdd20aSAndroid Build Coastguard Worker     while (!quit2) {
6435*6dbdd20aSAndroid Build Coastguard Worker       MockDataSource::Trace([&](MockDataSource::TraceContext ctx) {
6436*6dbdd20aSAndroid Build Coastguard Worker         {
6437*6dbdd20aSAndroid Build Coastguard Worker           auto packet = ctx.NewTracePacket();
6438*6dbdd20aSAndroid Build Coastguard Worker           packet->set_for_testing()->set_str("New session");
6439*6dbdd20aSAndroid Build Coastguard Worker         }
6440*6dbdd20aSAndroid Build Coastguard Worker         { auto packet = ctx.NewTracePacket(); }
6441*6dbdd20aSAndroid Build Coastguard Worker         tracing2.Notify();
6442*6dbdd20aSAndroid Build Coastguard Worker       });
6443*6dbdd20aSAndroid Build Coastguard Worker       std::this_thread::yield();
6444*6dbdd20aSAndroid Build Coastguard Worker     }
6445*6dbdd20aSAndroid Build Coastguard Worker   });
6446*6dbdd20aSAndroid Build Coastguard Worker   auto cleanup = MakeCleanup([&] {
6447*6dbdd20aSAndroid Build Coastguard Worker     if (t.joinable()) {
6448*6dbdd20aSAndroid Build Coastguard Worker       quit1 = true;
6449*6dbdd20aSAndroid Build Coastguard Worker       quit2 = true;
6450*6dbdd20aSAndroid Build Coastguard Worker       t.join();
6451*6dbdd20aSAndroid Build Coastguard Worker     }
6452*6dbdd20aSAndroid Build Coastguard Worker   });
6453*6dbdd20aSAndroid Build Coastguard Worker   tracing1.Wait();
6454*6dbdd20aSAndroid Build Coastguard Worker 
6455*6dbdd20aSAndroid Build Coastguard Worker   // Restarts the system service. This will cause the producer and consumer to
6456*6dbdd20aSAndroid Build Coastguard Worker   // disconnect.
6457*6dbdd20aSAndroid Build Coastguard Worker   system_service_.Restart();
6458*6dbdd20aSAndroid Build Coastguard Worker 
6459*6dbdd20aSAndroid Build Coastguard Worker   // The data source instance should be stopped. Don't acknowledge the stop yet.
6460*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop.Wait();
6461*6dbdd20aSAndroid Build Coastguard Worker 
6462*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->on_stop.Wait();
6463*6dbdd20aSAndroid Build Coastguard Worker 
6464*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<perfetto::TracingSession> new_session =
6465*6dbdd20aSAndroid Build Coastguard Worker       perfetto::Tracing::NewTrace(/*backend=*/GetParam());
6466*6dbdd20aSAndroid Build Coastguard Worker   // Wait for reconnection
6467*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(WaitForOneProducerConnected(new_session.get()));
6468*6dbdd20aSAndroid Build Coastguard Worker 
6469*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session2 = NewTrace(cfg);
6470*6dbdd20aSAndroid Build Coastguard Worker   tracing_session2->get()->StartBlocking();
6471*6dbdd20aSAndroid Build Coastguard Worker 
6472*6dbdd20aSAndroid Build Coastguard Worker   data_source->async_stop_closure();
6473*6dbdd20aSAndroid Build Coastguard Worker 
6474*6dbdd20aSAndroid Build Coastguard Worker   quit1 = true;
6475*6dbdd20aSAndroid Build Coastguard Worker   tracing2.Wait();
6476*6dbdd20aSAndroid Build Coastguard Worker   quit2 = true;
6477*6dbdd20aSAndroid Build Coastguard Worker   t.join();
6478*6dbdd20aSAndroid Build Coastguard Worker 
6479*6dbdd20aSAndroid Build Coastguard Worker   data_source->handle_stop_asynchronously = false;
6480*6dbdd20aSAndroid Build Coastguard Worker 
6481*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session2);
6482*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> test_strings;
6483*6dbdd20aSAndroid Build Coastguard Worker   for (auto& trace_packet : trace.packet()) {
6484*6dbdd20aSAndroid Build Coastguard Worker     if (trace_packet.has_for_testing()) {
6485*6dbdd20aSAndroid Build Coastguard Worker       test_strings.push_back(trace_packet.for_testing().str());
6486*6dbdd20aSAndroid Build Coastguard Worker     }
6487*6dbdd20aSAndroid Build Coastguard Worker   }
6488*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(test_strings, AllOf(Not(IsEmpty()), Each("New session")));
6489*6dbdd20aSAndroid Build Coastguard Worker }
6490*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,SystemDisconnectWhileStopping)6491*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, SystemDisconnectWhileStopping) {
6492*6dbdd20aSAndroid Build Coastguard Worker   if (GetParam() != perfetto::kSystemBackend) {
6493*6dbdd20aSAndroid Build Coastguard Worker     GTEST_SKIP();
6494*6dbdd20aSAndroid Build Coastguard Worker   }
6495*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source = &data_sources_["my_data_source"];
6496*6dbdd20aSAndroid Build Coastguard Worker   data_source->handle_stop_asynchronously = true;
6497*6dbdd20aSAndroid Build Coastguard Worker 
6498*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6499*6dbdd20aSAndroid Build Coastguard Worker   auto* buffer = cfg.add_buffers();
6500*6dbdd20aSAndroid Build Coastguard Worker   buffer->set_size_kb(64);
6501*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6502*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("my_data_source");
6503*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTrace(cfg);
6504*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6505*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_start.Wait();
6506*6dbdd20aSAndroid Build Coastguard Worker 
6507*6dbdd20aSAndroid Build Coastguard Worker   // Stop the session and wait until DataSource::OnStop is called. Don't
6508*6dbdd20aSAndroid Build Coastguard Worker   // complete the async stop yet.
6509*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->Stop();
6510*6dbdd20aSAndroid Build Coastguard Worker   data_source->on_stop.Wait();
6511*6dbdd20aSAndroid Build Coastguard Worker 
6512*6dbdd20aSAndroid Build Coastguard Worker   // Restart the service. This should not call DataSource::OnStop again while
6513*6dbdd20aSAndroid Build Coastguard Worker   // another async stop is in progress.
6514*6dbdd20aSAndroid Build Coastguard Worker   system_service_.Restart();
6515*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->on_stop.Wait();
6516*6dbdd20aSAndroid Build Coastguard Worker 
6517*6dbdd20aSAndroid Build Coastguard Worker   data_source->async_stop_closure();
6518*6dbdd20aSAndroid Build Coastguard Worker   data_source->handle_stop_asynchronously = false;
6519*6dbdd20aSAndroid Build Coastguard Worker }
6520*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoApiTest,CloneSession)6521*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoApiTest, CloneSession) {
6522*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6523*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_unique_session_name("test_session");
6524*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"}, {}, cfg);
6525*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6526*6dbdd20aSAndroid Build Coastguard Worker 
6527*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "TestEvent");
6528*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("test");
6529*6dbdd20aSAndroid Build Coastguard Worker 
6530*6dbdd20aSAndroid Build Coastguard Worker   sessions_.emplace_back();
6531*6dbdd20aSAndroid Build Coastguard Worker   TestTracingSessionHandle* other_tracing_session = &sessions_.back();
6532*6dbdd20aSAndroid Build Coastguard Worker   other_tracing_session->session =
6533*6dbdd20aSAndroid Build Coastguard Worker       perfetto::Tracing::NewTrace(/*backend_type=*/GetParam());
6534*6dbdd20aSAndroid Build Coastguard Worker 
6535*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent session_cloned;
6536*6dbdd20aSAndroid Build Coastguard Worker   other_tracing_session->get()->CloneTrace(
6537*6dbdd20aSAndroid Build Coastguard Worker       {"test_session"}, [&](perfetto::TracingSession::CloneTraceCallbackArgs) {
6538*6dbdd20aSAndroid Build Coastguard Worker         session_cloned.Notify();
6539*6dbdd20aSAndroid Build Coastguard Worker       });
6540*6dbdd20aSAndroid Build Coastguard Worker   session_cloned.Wait();
6541*6dbdd20aSAndroid Build Coastguard Worker 
6542*6dbdd20aSAndroid Build Coastguard Worker   {
6543*6dbdd20aSAndroid Build Coastguard Worker     std::vector<char> raw_trace =
6544*6dbdd20aSAndroid Build Coastguard Worker         other_tracing_session->get()->ReadTraceBlocking();
6545*6dbdd20aSAndroid Build Coastguard Worker     std::string trace(raw_trace.data(), raw_trace.size());
6546*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(trace, HasSubstr("TestEvent"));
6547*6dbdd20aSAndroid Build Coastguard Worker   }
6548*6dbdd20aSAndroid Build Coastguard Worker 
6549*6dbdd20aSAndroid Build Coastguard Worker   {
6550*6dbdd20aSAndroid Build Coastguard Worker     std::vector<char> raw_trace = StopSessionAndReturnBytes(tracing_session);
6551*6dbdd20aSAndroid Build Coastguard Worker     std::string trace(raw_trace.data(), raw_trace.size());
6552*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(trace, HasSubstr("TestEvent"));
6553*6dbdd20aSAndroid Build Coastguard Worker   }
6554*6dbdd20aSAndroid Build Coastguard Worker }
6555*6dbdd20aSAndroid Build Coastguard Worker 
6556*6dbdd20aSAndroid Build Coastguard Worker class PerfettoStartupTracingApiTest : public PerfettoApiTest {
6557*6dbdd20aSAndroid Build Coastguard Worker  public:
6558*6dbdd20aSAndroid Build Coastguard Worker   using SetupStartupTracingOpts = perfetto::Tracing::SetupStartupTracingOpts;
SetupStartupTracing(perfetto::TraceConfig cfg={},SetupStartupTracingOpts opts={})6559*6dbdd20aSAndroid Build Coastguard Worker   void SetupStartupTracing(perfetto::TraceConfig cfg = {},
6560*6dbdd20aSAndroid Build Coastguard Worker                            SetupStartupTracingOpts opts = {}) {
6561*6dbdd20aSAndroid Build Coastguard Worker     // Setup startup tracing in the current process.
6562*6dbdd20aSAndroid Build Coastguard Worker     cfg.set_duration_ms(500);
6563*6dbdd20aSAndroid Build Coastguard Worker     cfg.add_buffers()->set_size_kb(1024);
6564*6dbdd20aSAndroid Build Coastguard Worker     auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6565*6dbdd20aSAndroid Build Coastguard Worker     ds_cfg->set_name("track_event");
6566*6dbdd20aSAndroid Build Coastguard Worker 
6567*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TrackEventConfig te_cfg;
6568*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_disabled_categories("*");
6569*6dbdd20aSAndroid Build Coastguard Worker     te_cfg.add_enabled_categories("test");
6570*6dbdd20aSAndroid Build Coastguard Worker     ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
6571*6dbdd20aSAndroid Build Coastguard Worker 
6572*6dbdd20aSAndroid Build Coastguard Worker     opts.backend = GetParam();
6573*6dbdd20aSAndroid Build Coastguard Worker     session_ =
6574*6dbdd20aSAndroid Build Coastguard Worker         perfetto::Tracing::SetupStartupTracingBlocking(cfg, std::move(opts));
6575*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ(TRACE_EVENT_CATEGORY_ENABLED("test"), true);
6576*6dbdd20aSAndroid Build Coastguard Worker   }
6577*6dbdd20aSAndroid Build Coastguard Worker 
AbortStartupTracing()6578*6dbdd20aSAndroid Build Coastguard Worker   void AbortStartupTracing() {
6579*6dbdd20aSAndroid Build Coastguard Worker     session_->AbortBlocking();
6580*6dbdd20aSAndroid Build Coastguard Worker     session_.reset();
6581*6dbdd20aSAndroid Build Coastguard Worker   }
6582*6dbdd20aSAndroid Build Coastguard Worker 
TearDown()6583*6dbdd20aSAndroid Build Coastguard Worker   void TearDown() override {
6584*6dbdd20aSAndroid Build Coastguard Worker     if (session_) {
6585*6dbdd20aSAndroid Build Coastguard Worker       AbortStartupTracing();
6586*6dbdd20aSAndroid Build Coastguard Worker     }
6587*6dbdd20aSAndroid Build Coastguard Worker     // We need to sync producer because when we start StartupTracing, the
6588*6dbdd20aSAndroid Build Coastguard Worker     // producer is disconnected to reconnect again. Note that
6589*6dbdd20aSAndroid Build Coastguard Worker     // `SetupStartupTracingBlocking` returns right after data sources are
6590*6dbdd20aSAndroid Build Coastguard Worker     // started. `SetupStartupTracingBlocking` doesn't wait for reconnection
6591*6dbdd20aSAndroid Build Coastguard Worker     // to succeed before returning. Hence we need to wait for reconnection here
6592*6dbdd20aSAndroid Build Coastguard Worker     // because `TracingMuxerImpl::ResetForTesting` will destroy the
6593*6dbdd20aSAndroid Build Coastguard Worker     // producer if it find it is not connected to service. Which is problematic
6594*6dbdd20aSAndroid Build Coastguard Worker     // because when reconnection happens (via service transport), it will be
6595*6dbdd20aSAndroid Build Coastguard Worker     // referencing a deleted producer, which will lead to crash.
6596*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::SyncProducers();
6597*6dbdd20aSAndroid Build Coastguard Worker     this->PerfettoApiTest::TearDown();
6598*6dbdd20aSAndroid Build Coastguard Worker   }
6599*6dbdd20aSAndroid Build Coastguard Worker 
6600*6dbdd20aSAndroid Build Coastguard Worker  protected:
6601*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<perfetto::StartupTracingSession> session_;
6602*6dbdd20aSAndroid Build Coastguard Worker };
6603*6dbdd20aSAndroid Build Coastguard Worker 
6604*6dbdd20aSAndroid Build Coastguard Worker // Test `SetupStartupTracing` API (non block version).
TEST_P(PerfettoStartupTracingApiTest,NonBlockingAPI)6605*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, NonBlockingAPI) {
6606*6dbdd20aSAndroid Build Coastguard Worker   // Setup startup tracing in the current process.
6607*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6608*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
6609*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
6610*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6611*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
6612*6dbdd20aSAndroid Build Coastguard Worker 
6613*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TrackEventConfig te_cfg;
6614*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.add_disabled_categories("*");
6615*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.add_enabled_categories("test");
6616*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
6617*6dbdd20aSAndroid Build Coastguard Worker 
6618*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracingOpts opts;
6619*6dbdd20aSAndroid Build Coastguard Worker   opts.backend = GetParam();
6620*6dbdd20aSAndroid Build Coastguard Worker   session_ = perfetto::Tracing::SetupStartupTracing(cfg, std::move(opts));
6621*6dbdd20aSAndroid Build Coastguard Worker   // We need perfetto::test::SyncProducers() to Round-trip to ensure that the
6622*6dbdd20aSAndroid Build Coastguard Worker   // muxer has enabled startup tracing.
6623*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
6624*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(TRACE_EVENT_CATEGORY_ENABLED("test"), true);
6625*6dbdd20aSAndroid Build Coastguard Worker 
6626*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "Event");
6627*6dbdd20aSAndroid Build Coastguard Worker 
6628*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
6629*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6630*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6631*6dbdd20aSAndroid Build Coastguard Worker 
6632*6dbdd20aSAndroid Build Coastguard Worker   // Emit another event after starting.
6633*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("test");
6634*6dbdd20aSAndroid Build Coastguard Worker   // Both events should be retained.
6635*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6636*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.Event", "E"));
6637*6dbdd20aSAndroid Build Coastguard Worker }
6638*6dbdd20aSAndroid Build Coastguard Worker 
6639*6dbdd20aSAndroid Build Coastguard Worker // Test that a startup tracing session will be adopted even when the config
6640*6dbdd20aSAndroid Build Coastguard Worker // is not exactly identical (but still compatible).
TEST_P(PerfettoStartupTracingApiTest,CompatibleConfig)6641*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, CompatibleConfig) {
6642*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6643*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
6644*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
6645*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6646*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
6647*6dbdd20aSAndroid Build Coastguard Worker 
6648*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TrackEventConfig te_cfg;
6649*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.add_disabled_categories("*");
6650*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.add_enabled_categories("foo");
6651*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.add_enabled_categories("bar");
6652*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
6653*6dbdd20aSAndroid Build Coastguard Worker 
6654*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracingOpts opts;
6655*6dbdd20aSAndroid Build Coastguard Worker   opts.backend = GetParam();
6656*6dbdd20aSAndroid Build Coastguard Worker   session_ = perfetto::Tracing::SetupStartupTracing(cfg, std::move(opts));
6657*6dbdd20aSAndroid Build Coastguard Worker   // We need perfetto::test::SyncProducers() to Round-trip to ensure that the
6658*6dbdd20aSAndroid Build Coastguard Worker   // muxer has enabled startup tracing.
6659*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
6660*6dbdd20aSAndroid Build Coastguard Worker 
6661*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Event");
6662*6dbdd20aSAndroid Build Coastguard Worker 
6663*6dbdd20aSAndroid Build Coastguard Worker   // Note the different order of categories. The config is essentially the same,
6664*6dbdd20aSAndroid Build Coastguard Worker   // but is not byte-by-byte identical.
6665*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"bar", "foo"});
6666*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6667*6dbdd20aSAndroid Build Coastguard Worker 
6668*6dbdd20aSAndroid Build Coastguard Worker   // Emit another event after starting.
6669*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
6670*6dbdd20aSAndroid Build Coastguard Worker 
6671*6dbdd20aSAndroid Build Coastguard Worker   // Both events should be retained.
6672*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6673*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:foo.Event", "E"));
6674*6dbdd20aSAndroid Build Coastguard Worker }
6675*6dbdd20aSAndroid Build Coastguard Worker 
6676*6dbdd20aSAndroid Build Coastguard Worker // Test that a startup tracing session won't be adopted when the config is not
6677*6dbdd20aSAndroid Build Coastguard Worker // compatible (in this case, the privacy setting is different).
TEST_P(PerfettoStartupTracingApiTest,IncompatibleConfig)6678*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, IncompatibleConfig) {
6679*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6680*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
6681*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
6682*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6683*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
6684*6dbdd20aSAndroid Build Coastguard Worker 
6685*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TrackEventConfig te_cfg;
6686*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.add_disabled_categories("*");
6687*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.add_enabled_categories("foo");
6688*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.set_filter_debug_annotations(true);
6689*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
6690*6dbdd20aSAndroid Build Coastguard Worker 
6691*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracingOpts opts;
6692*6dbdd20aSAndroid Build Coastguard Worker   opts.backend = GetParam();
6693*6dbdd20aSAndroid Build Coastguard Worker   session_ = perfetto::Tracing::SetupStartupTracing(cfg, std::move(opts));
6694*6dbdd20aSAndroid Build Coastguard Worker   // We need perfetto::test::SyncProducers() to Round-trip to ensure that the
6695*6dbdd20aSAndroid Build Coastguard Worker   // muxer has enabled startup tracing.
6696*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
6697*6dbdd20aSAndroid Build Coastguard Worker 
6698*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("foo", "Event");
6699*6dbdd20aSAndroid Build Coastguard Worker 
6700*6dbdd20aSAndroid Build Coastguard Worker   // This config will have |filter_debug_annotations| set to false.
6701*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"foo"});
6702*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6703*6dbdd20aSAndroid Build Coastguard Worker 
6704*6dbdd20aSAndroid Build Coastguard Worker   // Emit another event after starting.
6705*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("foo");
6706*6dbdd20aSAndroid Build Coastguard Worker 
6707*6dbdd20aSAndroid Build Coastguard Worker   // The startup session should not be adopted, so we should only see the end
6708*6dbdd20aSAndroid Build Coastguard Worker   // event.
6709*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6710*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("E"));
6711*6dbdd20aSAndroid Build Coastguard Worker }
6712*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoStartupTracingApiTest,WithExistingSmb)6713*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, WithExistingSmb) {
6714*6dbdd20aSAndroid Build Coastguard Worker   {
6715*6dbdd20aSAndroid Build Coastguard Worker     // Start and tear down a first session, just to set up the SMB.
6716*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"foo"});
6717*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
6718*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StopBlocking();
6719*6dbdd20aSAndroid Build Coastguard Worker   }
6720*6dbdd20aSAndroid Build Coastguard Worker 
6721*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing();
6722*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "Event");
6723*6dbdd20aSAndroid Build Coastguard Worker 
6724*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
6725*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6726*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6727*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6728*6dbdd20aSAndroid Build Coastguard Worker 
6729*6dbdd20aSAndroid Build Coastguard Worker   // Emit another event after starting.
6730*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("test");
6731*6dbdd20aSAndroid Build Coastguard Worker 
6732*6dbdd20aSAndroid Build Coastguard Worker   // Both events should be retained.
6733*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6734*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.Event", "E"));
6735*6dbdd20aSAndroid Build Coastguard Worker }
6736*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoStartupTracingApiTest,WithProducerProvidedSmb)6737*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, WithProducerProvidedSmb) {
6738*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_FALSE(perfetto::test::TracingMuxerImplInternalsForTest::
6739*6dbdd20aSAndroid Build Coastguard Worker                    DoesSystemBackendHaveSMB());
6740*6dbdd20aSAndroid Build Coastguard Worker   // The backend has no SMB set up yet. Instead, the SDK will
6741*6dbdd20aSAndroid Build Coastguard Worker   // reconnect to the backend with a producer-provided SMB.
6742*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing();
6743*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "Event");
6744*6dbdd20aSAndroid Build Coastguard Worker 
6745*6dbdd20aSAndroid Build Coastguard Worker   // Create a new trace session.
6746*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6747*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6748*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6749*6dbdd20aSAndroid Build Coastguard Worker 
6750*6dbdd20aSAndroid Build Coastguard Worker   // Emit another event after starting.
6751*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("test");
6752*6dbdd20aSAndroid Build Coastguard Worker 
6753*6dbdd20aSAndroid Build Coastguard Worker   // Both events should be retained.
6754*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6755*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.Event", "E"));
6756*6dbdd20aSAndroid Build Coastguard Worker }
6757*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoStartupTracingApiTest,DontTraceBeforeStartupSetup)6758*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, DontTraceBeforeStartupSetup) {
6759*6dbdd20aSAndroid Build Coastguard Worker   // This event should not be recorded.
6760*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "EventBeforeStartupTrace");
6761*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing();
6762*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "Event");
6763*6dbdd20aSAndroid Build Coastguard Worker 
6764*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6765*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6766*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6767*6dbdd20aSAndroid Build Coastguard Worker 
6768*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_END("test");
6769*6dbdd20aSAndroid Build Coastguard Worker 
6770*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6771*6dbdd20aSAndroid Build Coastguard Worker 
6772*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.Event", "E"));
6773*6dbdd20aSAndroid Build Coastguard Worker }
6774*6dbdd20aSAndroid Build Coastguard Worker 
6775*6dbdd20aSAndroid Build Coastguard Worker // Test the StartupTracing when there are multiple data sources registered
6776*6dbdd20aSAndroid Build Coastguard Worker // (2 data sources in this test) but only a few of them contribute in startup
6777*6dbdd20aSAndroid Build Coastguard Worker // tracing.
TEST_P(PerfettoStartupTracingApiTest,MultipleDataSourceFewContributing)6778*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, MultipleDataSourceFewContributing) {
6779*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6780*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6781*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("CustomDataSource");
6782*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing(cfg);
6783*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "TrackEvent.Startup");
6784*6dbdd20aSAndroid Build Coastguard Worker 
6785*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"}, {}, cfg);
6786*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6787*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6788*6dbdd20aSAndroid Build Coastguard Worker 
6789*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "TrackEvent.Main");
6790*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Flush();
6791*6dbdd20aSAndroid Build Coastguard Worker   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
6792*6dbdd20aSAndroid Build Coastguard Worker     {
6793*6dbdd20aSAndroid Build Coastguard Worker       auto packet = ctx.NewTracePacket();
6794*6dbdd20aSAndroid Build Coastguard Worker       packet->set_for_testing()->set_str("CustomDataSource.Main");
6795*6dbdd20aSAndroid Build Coastguard Worker     }
6796*6dbdd20aSAndroid Build Coastguard Worker     ctx.Flush();
6797*6dbdd20aSAndroid Build Coastguard Worker   });
6798*6dbdd20aSAndroid Build Coastguard Worker 
6799*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
6800*6dbdd20aSAndroid Build Coastguard Worker   auto slices = ReadSlicesFromTrace(trace);
6801*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.TrackEvent.Startup",
6802*6dbdd20aSAndroid Build Coastguard Worker                                   "B:test.TrackEvent.Main"));
6803*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> test_strings;
6804*6dbdd20aSAndroid Build Coastguard Worker   for (auto& trace_packet : trace.packet()) {
6805*6dbdd20aSAndroid Build Coastguard Worker     if (trace_packet.has_for_testing()) {
6806*6dbdd20aSAndroid Build Coastguard Worker       test_strings.push_back(trace_packet.for_testing().str());
6807*6dbdd20aSAndroid Build Coastguard Worker     }
6808*6dbdd20aSAndroid Build Coastguard Worker   }
6809*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(test_strings, ElementsAre("CustomDataSource.Main"));
6810*6dbdd20aSAndroid Build Coastguard Worker }
6811*6dbdd20aSAndroid Build Coastguard Worker 
6812*6dbdd20aSAndroid Build Coastguard Worker // Test the StartupTracing when there are multiple data sources registered
6813*6dbdd20aSAndroid Build Coastguard Worker // (2 data sources in this test) and all of them are contributing in startup
6814*6dbdd20aSAndroid Build Coastguard Worker // tracing.
TEST_P(PerfettoStartupTracingApiTest,MultipleDataSourceAllContributing)6815*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, MultipleDataSourceAllContributing) {
6816*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
6817*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
6818*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("CustomDataSource");
6819*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing(cfg);
6820*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "TrackEvent.Startup");
6821*6dbdd20aSAndroid Build Coastguard Worker   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
6822*6dbdd20aSAndroid Build Coastguard Worker     auto packet = ctx.NewTracePacket();
6823*6dbdd20aSAndroid Build Coastguard Worker     packet->set_for_testing()->set_str("CustomDataSource.Startup");
6824*6dbdd20aSAndroid Build Coastguard Worker   });
6825*6dbdd20aSAndroid Build Coastguard Worker 
6826*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"}, {}, cfg);
6827*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6828*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6829*6dbdd20aSAndroid Build Coastguard Worker 
6830*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "TrackEvent.Main");
6831*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Flush();
6832*6dbdd20aSAndroid Build Coastguard Worker   CustomDataSource::Trace([](CustomDataSource::TraceContext ctx) {
6833*6dbdd20aSAndroid Build Coastguard Worker     {
6834*6dbdd20aSAndroid Build Coastguard Worker       auto packet = ctx.NewTracePacket();
6835*6dbdd20aSAndroid Build Coastguard Worker       packet->set_for_testing()->set_str("CustomDataSource.Main");
6836*6dbdd20aSAndroid Build Coastguard Worker     }
6837*6dbdd20aSAndroid Build Coastguard Worker     ctx.Flush();
6838*6dbdd20aSAndroid Build Coastguard Worker   });
6839*6dbdd20aSAndroid Build Coastguard Worker 
6840*6dbdd20aSAndroid Build Coastguard Worker   auto trace = StopSessionAndReturnParsedTrace(tracing_session);
6841*6dbdd20aSAndroid Build Coastguard Worker   auto slices = ReadSlicesFromTrace(trace);
6842*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.TrackEvent.Startup",
6843*6dbdd20aSAndroid Build Coastguard Worker                                   "B:test.TrackEvent.Main"));
6844*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> test_strings;
6845*6dbdd20aSAndroid Build Coastguard Worker   for (auto& trace_packet : trace.packet()) {
6846*6dbdd20aSAndroid Build Coastguard Worker     if (trace_packet.has_for_testing()) {
6847*6dbdd20aSAndroid Build Coastguard Worker       test_strings.push_back(trace_packet.for_testing().str());
6848*6dbdd20aSAndroid Build Coastguard Worker     }
6849*6dbdd20aSAndroid Build Coastguard Worker   }
6850*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(test_strings,
6851*6dbdd20aSAndroid Build Coastguard Worker               ElementsAre("CustomDataSource.Startup", "CustomDataSource.Main"));
6852*6dbdd20aSAndroid Build Coastguard Worker }
6853*6dbdd20aSAndroid Build Coastguard Worker 
6854*6dbdd20aSAndroid Build Coastguard Worker // Startup tracing requires BufferExhaustedPolicy::kDrop, i.e. once the SMB is
6855*6dbdd20aSAndroid Build Coastguard Worker // filled with startup events, any further events should be dropped.
6856*6dbdd20aSAndroid Build Coastguard Worker // TODO(b/261493947): fix or remove. go/aosp_ci_failure23
TEST_P(PerfettoStartupTracingApiTest,DISABLED_DropPolicy)6857*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, DISABLED_DropPolicy) {
6858*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing();
6859*6dbdd20aSAndroid Build Coastguard Worker   constexpr int kNumEvents = 100000;
6860*6dbdd20aSAndroid Build Coastguard Worker   for (int i = 0; i < kNumEvents; i++) {
6861*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", "StartupEvent");
6862*6dbdd20aSAndroid Build Coastguard Worker   }
6863*6dbdd20aSAndroid Build Coastguard Worker 
6864*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6865*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6866*6dbdd20aSAndroid Build Coastguard Worker 
6867*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6868*6dbdd20aSAndroid Build Coastguard Worker   std::unordered_map<std::string, int> freq_map;
6869*6dbdd20aSAndroid Build Coastguard Worker   for (auto& slice : slices) {
6870*6dbdd20aSAndroid Build Coastguard Worker     freq_map[slice]++;
6871*6dbdd20aSAndroid Build Coastguard Worker   }
6872*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_GT(freq_map["B:test.StartupEvent"], 0);
6873*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_LT(freq_map["B:test.StartupEvent"], kNumEvents);
6874*6dbdd20aSAndroid Build Coastguard Worker }
6875*6dbdd20aSAndroid Build Coastguard Worker 
6876*6dbdd20aSAndroid Build Coastguard Worker // TODO(b/261493947): fix or remove.
TEST_P(PerfettoStartupTracingApiTest,DISABLED_Abort)6877*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, DISABLED_Abort) {
6878*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing();
6879*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "StartupEvent");
6880*6dbdd20aSAndroid Build Coastguard Worker   AbortStartupTracing();
6881*6dbdd20aSAndroid Build Coastguard Worker 
6882*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6883*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6884*6dbdd20aSAndroid Build Coastguard Worker 
6885*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "MainEvent");
6886*6dbdd20aSAndroid Build Coastguard Worker 
6887*6dbdd20aSAndroid Build Coastguard Worker   auto slices = StopSessionAndReadSlicesFromTrace(tracing_session);
6888*6dbdd20aSAndroid Build Coastguard Worker 
6889*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
6890*6dbdd20aSAndroid Build Coastguard Worker }
6891*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoStartupTracingApiTest,AbortAndRestart)6892*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, AbortAndRestart) {
6893*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing();
6894*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "StartupEvent1");
6895*6dbdd20aSAndroid Build Coastguard Worker   AbortStartupTracing();
6896*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing();
6897*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "StartupEvent2");
6898*6dbdd20aSAndroid Build Coastguard Worker 
6899*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6900*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6901*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6902*6dbdd20aSAndroid Build Coastguard Worker 
6903*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "MainEvent");
6904*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Flush();
6905*6dbdd20aSAndroid Build Coastguard Worker 
6906*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
6907*6dbdd20aSAndroid Build Coastguard Worker 
6908*6dbdd20aSAndroid Build Coastguard Worker   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
6909*6dbdd20aSAndroid Build Coastguard Worker 
6910*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.StartupEvent2", "B:test.MainEvent"));
6911*6dbdd20aSAndroid Build Coastguard Worker }
6912*6dbdd20aSAndroid Build Coastguard Worker 
TEST_P(PerfettoStartupTracingApiTest,Timeout)6913*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, Timeout) {
6914*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracingOpts args;
6915*6dbdd20aSAndroid Build Coastguard Worker   args.timeout_ms = 2000;
6916*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing({}, args);
6917*6dbdd20aSAndroid Build Coastguard Worker   for (int i = 0; i < 25; i++) {
6918*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", "StartupEvent");
6919*6dbdd20aSAndroid Build Coastguard Worker     std::this_thread::sleep_for(std::chrono::milliseconds(100));
6920*6dbdd20aSAndroid Build Coastguard Worker   }
6921*6dbdd20aSAndroid Build Coastguard Worker 
6922*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6923*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6924*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "MainEvent");
6925*6dbdd20aSAndroid Build Coastguard Worker 
6926*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Flush();
6927*6dbdd20aSAndroid Build Coastguard Worker 
6928*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
6929*6dbdd20aSAndroid Build Coastguard Worker 
6930*6dbdd20aSAndroid Build Coastguard Worker   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
6931*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
6932*6dbdd20aSAndroid Build Coastguard Worker }
6933*6dbdd20aSAndroid Build Coastguard Worker 
6934*6dbdd20aSAndroid Build Coastguard Worker // TODO(b/261493947): fix or remove.
TEST_P(PerfettoStartupTracingApiTest,DISABLED_Callbacks)6935*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, DISABLED_Callbacks) {
6936*6dbdd20aSAndroid Build Coastguard Worker   for (bool abort : {true, false}) {
6937*6dbdd20aSAndroid Build Coastguard Worker     SetupStartupTracingOpts args;
6938*6dbdd20aSAndroid Build Coastguard Worker     std::vector<std::string> callback_events;
6939*6dbdd20aSAndroid Build Coastguard Worker     using CallbackArgs = perfetto::Tracing::OnStartupTracingSetupCallbackArgs;
6940*6dbdd20aSAndroid Build Coastguard Worker     args.on_setup = [&](CallbackArgs callback_arg) {
6941*6dbdd20aSAndroid Build Coastguard Worker       callback_events.push_back(
6942*6dbdd20aSAndroid Build Coastguard Worker           "OnSetup(num_data_sources_started=" +
6943*6dbdd20aSAndroid Build Coastguard Worker           std::to_string(callback_arg.num_data_sources_started) + ")");
6944*6dbdd20aSAndroid Build Coastguard Worker     };
6945*6dbdd20aSAndroid Build Coastguard Worker     args.on_adopted = [&]() { callback_events.push_back("OnAdopted()"); };
6946*6dbdd20aSAndroid Build Coastguard Worker     args.on_aborted = [&]() { callback_events.push_back("OnAborted()"); };
6947*6dbdd20aSAndroid Build Coastguard Worker     SetupStartupTracing({}, args);
6948*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", "StartupEvent");
6949*6dbdd20aSAndroid Build Coastguard Worker     if (abort) {
6950*6dbdd20aSAndroid Build Coastguard Worker       AbortStartupTracing();
6951*6dbdd20aSAndroid Build Coastguard Worker     }
6952*6dbdd20aSAndroid Build Coastguard Worker     auto* tracing_session = NewTraceWithCategories({"test"});
6953*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StartBlocking();
6954*6dbdd20aSAndroid Build Coastguard Worker 
6955*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_BEGIN("test", "MainEvent");
6956*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::Flush();
6957*6dbdd20aSAndroid Build Coastguard Worker 
6958*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->get()->StopBlocking();
6959*6dbdd20aSAndroid Build Coastguard Worker 
6960*6dbdd20aSAndroid Build Coastguard Worker     auto slices = ReadSlicesFromTraceSession(tracing_session->get());
6961*6dbdd20aSAndroid Build Coastguard Worker 
6962*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_EQ(2u, callback_events.size());
6963*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_EQ("OnSetup(num_data_sources_started=1)", callback_events.at(0));
6964*6dbdd20aSAndroid Build Coastguard Worker     if (abort) {
6965*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
6966*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("OnAborted()", callback_events.at(1));
6967*6dbdd20aSAndroid Build Coastguard Worker     } else {
6968*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_THAT(slices,
6969*6dbdd20aSAndroid Build Coastguard Worker                   ElementsAre("B:test.StartupEvent", "B:test.MainEvent"));
6970*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ("OnAdopted()", callback_events.at(1));
6971*6dbdd20aSAndroid Build Coastguard Worker     }
6972*6dbdd20aSAndroid Build Coastguard Worker   }
6973*6dbdd20aSAndroid Build Coastguard Worker }
6974*6dbdd20aSAndroid Build Coastguard Worker 
6975*6dbdd20aSAndroid Build Coastguard Worker // Test that it's ok if main tracing is never started.
6976*6dbdd20aSAndroid Build Coastguard Worker // TODO(b/261493947): fix or remove.
TEST_P(PerfettoStartupTracingApiTest,DISABLED_MainTracingNeverStarted)6977*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, DISABLED_MainTracingNeverStarted) {
6978*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing();
6979*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "StartupEvent");
6980*6dbdd20aSAndroid Build Coastguard Worker }
6981*6dbdd20aSAndroid Build Coastguard Worker 
6982*6dbdd20aSAndroid Build Coastguard Worker // Validates that Startup Trace works fine if we dont emit any event
6983*6dbdd20aSAndroid Build Coastguard Worker // during startup tracing session.
TEST_P(PerfettoStartupTracingApiTest,NoEventInStartupTracing)6984*6dbdd20aSAndroid Build Coastguard Worker TEST_P(PerfettoStartupTracingApiTest, NoEventInStartupTracing) {
6985*6dbdd20aSAndroid Build Coastguard Worker   SetupStartupTracing();
6986*6dbdd20aSAndroid Build Coastguard Worker 
6987*6dbdd20aSAndroid Build Coastguard Worker   auto* tracing_session = NewTraceWithCategories({"test"});
6988*6dbdd20aSAndroid Build Coastguard Worker   ASSERT_TRUE(WaitForOneProducerConnected(tracing_session->get()));
6989*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StartBlocking();
6990*6dbdd20aSAndroid Build Coastguard Worker   // Emit an event now that the session was fully started. This should go
6991*6dbdd20aSAndroid Build Coastguard Worker   // strait to the SMB.
6992*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "MainEvent");
6993*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Flush();
6994*6dbdd20aSAndroid Build Coastguard Worker   tracing_session->get()->StopBlocking();
6995*6dbdd20aSAndroid Build Coastguard Worker   auto slices = ReadSlicesFromTraceSession(tracing_session->get());
6996*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices, ElementsAre("B:test.MainEvent"));
6997*6dbdd20aSAndroid Build Coastguard Worker }
6998*6dbdd20aSAndroid Build Coastguard Worker 
6999*6dbdd20aSAndroid Build Coastguard Worker class ConcurrentSessionTest : public ::testing::Test {
7000*6dbdd20aSAndroid Build Coastguard Worker  public:
SetUp()7001*6dbdd20aSAndroid Build Coastguard Worker   void SetUp() override {
7002*6dbdd20aSAndroid Build Coastguard Worker     system_service_ = perfetto::test::SystemService::Start();
7003*6dbdd20aSAndroid Build Coastguard Worker     if (!system_service_.valid()) {
7004*6dbdd20aSAndroid Build Coastguard Worker       GTEST_SKIP();
7005*6dbdd20aSAndroid Build Coastguard Worker     }
7006*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_FALSE(perfetto::Tracing::IsInitialized());
7007*6dbdd20aSAndroid Build Coastguard Worker   }
7008*6dbdd20aSAndroid Build Coastguard Worker 
InitPerfetto(bool supports_multiple_data_source_instances=true)7009*6dbdd20aSAndroid Build Coastguard Worker   void InitPerfetto(bool supports_multiple_data_source_instances = true) {
7010*6dbdd20aSAndroid Build Coastguard Worker     TracingInitArgs args;
7011*6dbdd20aSAndroid Build Coastguard Worker     args.backends = perfetto::kInProcessBackend | perfetto::kSystemBackend;
7012*6dbdd20aSAndroid Build Coastguard Worker     args.supports_multiple_data_source_instances =
7013*6dbdd20aSAndroid Build Coastguard Worker         supports_multiple_data_source_instances;
7014*6dbdd20aSAndroid Build Coastguard Worker     g_test_tracing_policy->should_allow_consumer_connection = true;
7015*6dbdd20aSAndroid Build Coastguard Worker     args.tracing_policy = g_test_tracing_policy;
7016*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Tracing::Initialize(args);
7017*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::Register();
7018*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::SyncProducers();
7019*6dbdd20aSAndroid Build Coastguard Worker     perfetto::test::DisableReconnectLimit();
7020*6dbdd20aSAndroid Build Coastguard Worker   }
7021*6dbdd20aSAndroid Build Coastguard Worker 
TearDown()7022*6dbdd20aSAndroid Build Coastguard Worker   void TearDown() override { perfetto::Tracing::ResetForTesting(); }
7023*6dbdd20aSAndroid Build Coastguard Worker 
StartTracing(perfetto::BackendType backend_type,bool short_stop_timeout=false)7024*6dbdd20aSAndroid Build Coastguard Worker   static std::unique_ptr<perfetto::TracingSession> StartTracing(
7025*6dbdd20aSAndroid Build Coastguard Worker       perfetto::BackendType backend_type,
7026*6dbdd20aSAndroid Build Coastguard Worker       bool short_stop_timeout = false) {
7027*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TraceConfig cfg;
7028*6dbdd20aSAndroid Build Coastguard Worker     if (short_stop_timeout) {
7029*6dbdd20aSAndroid Build Coastguard Worker       cfg.set_data_source_stop_timeout_ms(500);
7030*6dbdd20aSAndroid Build Coastguard Worker     }
7031*6dbdd20aSAndroid Build Coastguard Worker     cfg.add_buffers()->set_size_kb(1024);
7032*6dbdd20aSAndroid Build Coastguard Worker     auto* ds_cfg = cfg.add_data_sources()->mutable_config();
7033*6dbdd20aSAndroid Build Coastguard Worker     ds_cfg->set_name("track_event");
7034*6dbdd20aSAndroid Build Coastguard Worker     auto tracing_session = perfetto::Tracing::NewTrace(backend_type);
7035*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->Setup(cfg);
7036*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->StartBlocking();
7037*6dbdd20aSAndroid Build Coastguard Worker     return tracing_session;
7038*6dbdd20aSAndroid Build Coastguard Worker   }
StopTracing(std::unique_ptr<perfetto::TracingSession> tracing_session,bool expect_incremental_state_cleared=true)7039*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> StopTracing(
7040*6dbdd20aSAndroid Build Coastguard Worker       std::unique_ptr<perfetto::TracingSession> tracing_session,
7041*6dbdd20aSAndroid Build Coastguard Worker       bool expect_incremental_state_cleared = true) {
7042*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TrackEvent::Flush();
7043*6dbdd20aSAndroid Build Coastguard Worker     tracing_session->StopBlocking();
7044*6dbdd20aSAndroid Build Coastguard Worker     std::vector<char> trace_data(tracing_session->ReadTraceBlocking());
7045*6dbdd20aSAndroid Build Coastguard Worker     return ReadSlicesFromTrace(trace_data, expect_incremental_state_cleared);
7046*6dbdd20aSAndroid Build Coastguard Worker   }
7047*6dbdd20aSAndroid Build Coastguard Worker 
7048*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SystemService system_service_;
7049*6dbdd20aSAndroid Build Coastguard Worker };
7050*6dbdd20aSAndroid Build Coastguard Worker 
7051*6dbdd20aSAndroid Build Coastguard Worker // Verify that concurrent sessions works well by default.
7052*6dbdd20aSAndroid Build Coastguard Worker // (i.e. when `disallow_concurrent_sessions` param is not set)
TEST_F(ConcurrentSessionTest,ConcurrentBackends)7053*6dbdd20aSAndroid Build Coastguard Worker TEST_F(ConcurrentSessionTest, ConcurrentBackends) {
7054*6dbdd20aSAndroid Build Coastguard Worker   InitPerfetto();
7055*6dbdd20aSAndroid Build Coastguard Worker   auto tracing_session1 = StartTracing(perfetto::kSystemBackend);
7056*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "DrawGame1");
7057*6dbdd20aSAndroid Build Coastguard Worker 
7058*6dbdd20aSAndroid Build Coastguard Worker   auto tracing_session2 = StartTracing(perfetto::kInProcessBackend);
7059*6dbdd20aSAndroid Build Coastguard Worker   // Should be recorded by both sessions.
7060*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "DrawGame2");
7061*6dbdd20aSAndroid Build Coastguard Worker 
7062*6dbdd20aSAndroid Build Coastguard Worker   auto slices1 = StopTracing(std::move(tracing_session1));
7063*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices1, ElementsAre("B:test.DrawGame1", "B:test.DrawGame2"));
7064*6dbdd20aSAndroid Build Coastguard Worker 
7065*6dbdd20aSAndroid Build Coastguard Worker   auto slices2 = StopTracing(std::move(tracing_session2));
7066*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices2, ElementsAre("B:test.DrawGame2"));
7067*6dbdd20aSAndroid Build Coastguard Worker 
7068*6dbdd20aSAndroid Build Coastguard Worker   auto tracing_session3 = StartTracing(perfetto::kInProcessBackend);
7069*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "DrawGame3");
7070*6dbdd20aSAndroid Build Coastguard Worker 
7071*6dbdd20aSAndroid Build Coastguard Worker   auto slices3 = StopTracing(std::move(tracing_session3));
7072*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices3, ElementsAre("B:test.DrawGame3"));
7073*6dbdd20aSAndroid Build Coastguard Worker }
7074*6dbdd20aSAndroid Build Coastguard Worker 
7075*6dbdd20aSAndroid Build Coastguard Worker // When `supports_multiple_data_source_instances = false`, second session
7076*6dbdd20aSAndroid Build Coastguard Worker // should not be started.
TEST_F(ConcurrentSessionTest,DisallowMultipleSessionBasic)7077*6dbdd20aSAndroid Build Coastguard Worker TEST_F(ConcurrentSessionTest, DisallowMultipleSessionBasic) {
7078*6dbdd20aSAndroid Build Coastguard Worker   InitPerfetto(/* supports_multiple_data_source_instances = */ false);
7079*6dbdd20aSAndroid Build Coastguard Worker   auto tracing_session1 = StartTracing(perfetto::kInProcessBackend);
7080*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "DrawGame1");
7081*6dbdd20aSAndroid Build Coastguard Worker 
7082*6dbdd20aSAndroid Build Coastguard Worker   auto tracing_session2 =
7083*6dbdd20aSAndroid Build Coastguard Worker       StartTracing(perfetto::kInProcessBackend, /*short_stop_timeout=*/true);
7084*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "DrawGame2");
7085*6dbdd20aSAndroid Build Coastguard Worker 
7086*6dbdd20aSAndroid Build Coastguard Worker   auto slices1 = StopTracing(std::move(tracing_session1));
7087*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices1, ElementsAre("B:test.DrawGame1", "B:test.DrawGame2"));
7088*6dbdd20aSAndroid Build Coastguard Worker 
7089*6dbdd20aSAndroid Build Coastguard Worker   auto slices2 = StopTracing(std::move(tracing_session2),
7090*6dbdd20aSAndroid Build Coastguard Worker                              false /* expect_incremental_state_cleared */);
7091*6dbdd20aSAndroid Build Coastguard Worker   // Because `tracing_session2` was not really started.
7092*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices2, ElementsAre());
7093*6dbdd20aSAndroid Build Coastguard Worker 
7094*6dbdd20aSAndroid Build Coastguard Worker   auto tracing_session3 = StartTracing(perfetto::kInProcessBackend);
7095*6dbdd20aSAndroid Build Coastguard Worker   TRACE_EVENT_BEGIN("test", "DrawGame3");
7096*6dbdd20aSAndroid Build Coastguard Worker 
7097*6dbdd20aSAndroid Build Coastguard Worker   auto slices3 = StopTracing(std::move(tracing_session3));
7098*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_THAT(slices3, ElementsAre("B:test.DrawGame3"));
7099*6dbdd20aSAndroid Build Coastguard Worker }
7100*6dbdd20aSAndroid Build Coastguard Worker 
TEST(PerfettoApiInitTest,DisableSystemConsumer)7101*6dbdd20aSAndroid Build Coastguard Worker TEST(PerfettoApiInitTest, DisableSystemConsumer) {
7102*6dbdd20aSAndroid Build Coastguard Worker   g_test_tracing_policy->should_allow_consumer_connection = true;
7103*6dbdd20aSAndroid Build Coastguard Worker 
7104*6dbdd20aSAndroid Build Coastguard Worker   auto system_service = perfetto::test::SystemService::Start();
7105*6dbdd20aSAndroid Build Coastguard Worker   // If the system backend isn't supported, skip
7106*6dbdd20aSAndroid Build Coastguard Worker   if (!system_service.valid()) {
7107*6dbdd20aSAndroid Build Coastguard Worker     GTEST_SKIP();
7108*6dbdd20aSAndroid Build Coastguard Worker   }
7109*6dbdd20aSAndroid Build Coastguard Worker 
7110*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::Tracing::IsInitialized());
7111*6dbdd20aSAndroid Build Coastguard Worker   TracingInitArgs args;
7112*6dbdd20aSAndroid Build Coastguard Worker   args.backends = perfetto::kSystemBackend;
7113*6dbdd20aSAndroid Build Coastguard Worker   args.tracing_policy = g_test_tracing_policy;
7114*6dbdd20aSAndroid Build Coastguard Worker   args.enable_system_consumer = false;
7115*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::Initialize(args);
7116*6dbdd20aSAndroid Build Coastguard Worker 
7117*6dbdd20aSAndroid Build Coastguard Worker   // If this wasn't the first test to run in this process, any producers
7118*6dbdd20aSAndroid Build Coastguard Worker   // connected to the old system service will have been disconnected by the
7119*6dbdd20aSAndroid Build Coastguard Worker   // service restarting above. Wait for all producers to connect again before
7120*6dbdd20aSAndroid Build Coastguard Worker   // proceeding with the test.
7121*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
7122*6dbdd20aSAndroid Build Coastguard Worker 
7123*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::DisableReconnectLimit();
7124*6dbdd20aSAndroid Build Coastguard Worker 
7125*6dbdd20aSAndroid Build Coastguard Worker   // Creating the consumer with kUnspecifiedBackend should cause a connection
7126*6dbdd20aSAndroid Build Coastguard Worker   // error: there's no consumer backend.
7127*6dbdd20aSAndroid Build Coastguard Worker   {
7128*6dbdd20aSAndroid Build Coastguard Worker     std::unique_ptr<perfetto::TracingSession> ts =
7129*6dbdd20aSAndroid Build Coastguard Worker         perfetto::Tracing::NewTrace(perfetto::kUnspecifiedBackend);
7130*6dbdd20aSAndroid Build Coastguard Worker 
7131*6dbdd20aSAndroid Build Coastguard Worker     WaitableTestEvent got_error;
7132*6dbdd20aSAndroid Build Coastguard Worker     ts->SetOnErrorCallback([&](perfetto::TracingError error) {
7133*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_EQ(perfetto::TracingError::kDisconnected, error.code);
7134*6dbdd20aSAndroid Build Coastguard Worker       EXPECT_FALSE(error.message.empty());
7135*6dbdd20aSAndroid Build Coastguard Worker       got_error.Notify();
7136*6dbdd20aSAndroid Build Coastguard Worker     });
7137*6dbdd20aSAndroid Build Coastguard Worker     got_error.Wait();
7138*6dbdd20aSAndroid Build Coastguard Worker   }
7139*6dbdd20aSAndroid Build Coastguard Worker 
7140*6dbdd20aSAndroid Build Coastguard Worker   // Creating the consumer with kSystemBackend should create a system consumer
7141*6dbdd20aSAndroid Build Coastguard Worker   // backend on the spot.
7142*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(perfetto::Tracing::NewTrace(perfetto::kSystemBackend)
7143*6dbdd20aSAndroid Build Coastguard Worker                   ->QueryServiceStateBlocking()
7144*6dbdd20aSAndroid Build Coastguard Worker                   .success);
7145*6dbdd20aSAndroid Build Coastguard Worker 
7146*6dbdd20aSAndroid Build Coastguard Worker   // Now even a consumer with kUnspecifiedBackend should succeed, because the
7147*6dbdd20aSAndroid Build Coastguard Worker   // backend has been created.
7148*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(perfetto::Tracing::NewTrace(perfetto::kUnspecifiedBackend)
7149*6dbdd20aSAndroid Build Coastguard Worker                   ->QueryServiceStateBlocking()
7150*6dbdd20aSAndroid Build Coastguard Worker                   .success);
7151*6dbdd20aSAndroid Build Coastguard Worker 
7152*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::ResetForTesting();
7153*6dbdd20aSAndroid Build Coastguard Worker }
7154*6dbdd20aSAndroid Build Coastguard Worker 
TEST(PerfettoApiInitTest,SeparateInitializations)7155*6dbdd20aSAndroid Build Coastguard Worker TEST(PerfettoApiInitTest, SeparateInitializations) {
7156*6dbdd20aSAndroid Build Coastguard Worker   auto system_service = perfetto::test::SystemService::Start();
7157*6dbdd20aSAndroid Build Coastguard Worker   // If the system backend isn't supported, skip
7158*6dbdd20aSAndroid Build Coastguard Worker   if (!system_service.valid()) {
7159*6dbdd20aSAndroid Build Coastguard Worker     GTEST_SKIP();
7160*6dbdd20aSAndroid Build Coastguard Worker   }
7161*6dbdd20aSAndroid Build Coastguard Worker 
7162*6dbdd20aSAndroid Build Coastguard Worker   {
7163*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_FALSE(perfetto::Tracing::IsInitialized());
7164*6dbdd20aSAndroid Build Coastguard Worker     TracingInitArgs args;
7165*6dbdd20aSAndroid Build Coastguard Worker     args.backends = perfetto::kInProcessBackend;
7166*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Tracing::Initialize(args);
7167*6dbdd20aSAndroid Build Coastguard Worker   }
7168*6dbdd20aSAndroid Build Coastguard Worker 
7169*6dbdd20aSAndroid Build Coastguard Worker   // If this wasn't the first test to run in this process, any producers
7170*6dbdd20aSAndroid Build Coastguard Worker   // connected to the old system service will have been disconnected by the
7171*6dbdd20aSAndroid Build Coastguard Worker   // service restarting above. Wait for all producers to connect again before
7172*6dbdd20aSAndroid Build Coastguard Worker   // proceeding with the test.
7173*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
7174*6dbdd20aSAndroid Build Coastguard Worker 
7175*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::DisableReconnectLimit();
7176*6dbdd20aSAndroid Build Coastguard Worker 
7177*6dbdd20aSAndroid Build Coastguard Worker   {
7178*6dbdd20aSAndroid Build Coastguard Worker     perfetto::DataSourceDescriptor dsd;
7179*6dbdd20aSAndroid Build Coastguard Worker     dsd.set_name("CustomDataSource");
7180*6dbdd20aSAndroid Build Coastguard Worker     CustomDataSource::Register(dsd);
7181*6dbdd20aSAndroid Build Coastguard Worker   }
7182*6dbdd20aSAndroid Build Coastguard Worker 
7183*6dbdd20aSAndroid Build Coastguard Worker   {
7184*6dbdd20aSAndroid Build Coastguard Worker     std::unique_ptr<perfetto::TracingSession> tracing_session =
7185*6dbdd20aSAndroid Build Coastguard Worker         perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
7186*6dbdd20aSAndroid Build Coastguard Worker     auto result = tracing_session->QueryServiceStateBlocking();
7187*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TracingServiceState state;
7188*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_TRUE(result.success);
7189*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_TRUE(state.ParseFromArray(result.service_state_data.data(),
7190*6dbdd20aSAndroid Build Coastguard Worker                                      result.service_state_data.size()));
7191*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(state.data_sources(),
7192*6dbdd20aSAndroid Build Coastguard Worker                 Contains(Property(
7193*6dbdd20aSAndroid Build Coastguard Worker                     &perfetto::protos::gen::TracingServiceState::DataSource::
7194*6dbdd20aSAndroid Build Coastguard Worker                         ds_descriptor,
7195*6dbdd20aSAndroid Build Coastguard Worker                     Property(&perfetto::protos::gen::DataSourceDescriptor::name,
7196*6dbdd20aSAndroid Build Coastguard Worker                              "CustomDataSource"))));
7197*6dbdd20aSAndroid Build Coastguard Worker   }
7198*6dbdd20aSAndroid Build Coastguard Worker 
7199*6dbdd20aSAndroid Build Coastguard Worker   {
7200*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_TRUE(perfetto::Tracing::IsInitialized());
7201*6dbdd20aSAndroid Build Coastguard Worker     TracingInitArgs args;
7202*6dbdd20aSAndroid Build Coastguard Worker     args.backends = perfetto::kSystemBackend;
7203*6dbdd20aSAndroid Build Coastguard Worker     args.enable_system_consumer = false;
7204*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Tracing::Initialize(args);
7205*6dbdd20aSAndroid Build Coastguard Worker   }
7206*6dbdd20aSAndroid Build Coastguard Worker 
7207*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
7208*6dbdd20aSAndroid Build Coastguard Worker 
7209*6dbdd20aSAndroid Build Coastguard Worker   {
7210*6dbdd20aSAndroid Build Coastguard Worker     std::unique_ptr<perfetto::TracingSession> tracing_session =
7211*6dbdd20aSAndroid Build Coastguard Worker         perfetto::Tracing::NewTrace(perfetto::kSystemBackend);
7212*6dbdd20aSAndroid Build Coastguard Worker     auto result = tracing_session->QueryServiceStateBlocking();
7213*6dbdd20aSAndroid Build Coastguard Worker     perfetto::protos::gen::TracingServiceState state;
7214*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_TRUE(result.success);
7215*6dbdd20aSAndroid Build Coastguard Worker     ASSERT_TRUE(state.ParseFromArray(result.service_state_data.data(),
7216*6dbdd20aSAndroid Build Coastguard Worker                                      result.service_state_data.size()));
7217*6dbdd20aSAndroid Build Coastguard Worker     EXPECT_THAT(state.data_sources(),
7218*6dbdd20aSAndroid Build Coastguard Worker                 Contains(Property(
7219*6dbdd20aSAndroid Build Coastguard Worker                     &perfetto::protos::gen::TracingServiceState::DataSource::
7220*6dbdd20aSAndroid Build Coastguard Worker                         ds_descriptor,
7221*6dbdd20aSAndroid Build Coastguard Worker                     Property(&perfetto::protos::gen::DataSourceDescriptor::name,
7222*6dbdd20aSAndroid Build Coastguard Worker                              "CustomDataSource"))));
7223*6dbdd20aSAndroid Build Coastguard Worker   }
7224*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::TracingMuxerImplInternalsForTest::
7225*6dbdd20aSAndroid Build Coastguard Worker       ClearDataSourceTlsStateOnReset<CustomDataSource>();
7226*6dbdd20aSAndroid Build Coastguard Worker 
7227*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::ResetForTesting();
7228*6dbdd20aSAndroid Build Coastguard Worker }
7229*6dbdd20aSAndroid Build Coastguard Worker 
7230*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7231*6dbdd20aSAndroid Build Coastguard Worker namespace {
7232*6dbdd20aSAndroid Build Coastguard Worker 
ConnectUnixSocket()7233*6dbdd20aSAndroid Build Coastguard Worker int ConnectUnixSocket() {
7234*6dbdd20aSAndroid Build Coastguard Worker   std::string socket_name = perfetto::GetProducerSocket();
7235*6dbdd20aSAndroid Build Coastguard Worker   int fd = socket(AF_UNIX, SOCK_STREAM, 0);
7236*6dbdd20aSAndroid Build Coastguard Worker   struct sockaddr_un saddr;
7237*6dbdd20aSAndroid Build Coastguard Worker   memset(&saddr, 0, sizeof(saddr));
7238*6dbdd20aSAndroid Build Coastguard Worker   memcpy(saddr.sun_path, socket_name.data(), socket_name.size());
7239*6dbdd20aSAndroid Build Coastguard Worker   saddr.sun_family = AF_UNIX;
7240*6dbdd20aSAndroid Build Coastguard Worker   auto size = static_cast<socklen_t>(__builtin_offsetof(sockaddr_un, sun_path) +
7241*6dbdd20aSAndroid Build Coastguard Worker                                      socket_name.size() + 1);
7242*6dbdd20aSAndroid Build Coastguard Worker   connect(fd, reinterpret_cast<const struct sockaddr*>(&saddr), size);
7243*6dbdd20aSAndroid Build Coastguard Worker   return fd;
7244*6dbdd20aSAndroid Build Coastguard Worker }
7245*6dbdd20aSAndroid Build Coastguard Worker 
7246*6dbdd20aSAndroid Build Coastguard Worker using CreateSocketFunction =
7247*6dbdd20aSAndroid Build Coastguard Worker     std::function<void(perfetto::CreateSocketCallback)>;
7248*6dbdd20aSAndroid Build Coastguard Worker 
7249*6dbdd20aSAndroid Build Coastguard Worker CreateSocketFunction* g_std_function = nullptr;
7250*6dbdd20aSAndroid Build Coastguard Worker 
SetCreateSocketFunction(CreateSocketFunction func)7251*6dbdd20aSAndroid Build Coastguard Worker void SetCreateSocketFunction(CreateSocketFunction func) {
7252*6dbdd20aSAndroid Build Coastguard Worker   g_std_function = new CreateSocketFunction(func);
7253*6dbdd20aSAndroid Build Coastguard Worker }
7254*6dbdd20aSAndroid Build Coastguard Worker 
ResetCreateSocketFunction()7255*6dbdd20aSAndroid Build Coastguard Worker void ResetCreateSocketFunction() {
7256*6dbdd20aSAndroid Build Coastguard Worker   delete g_std_function;
7257*6dbdd20aSAndroid Build Coastguard Worker }
7258*6dbdd20aSAndroid Build Coastguard Worker 
CallCreateSocketFunction(perfetto::CreateSocketCallback cb)7259*6dbdd20aSAndroid Build Coastguard Worker void CallCreateSocketFunction(perfetto::CreateSocketCallback cb) {
7260*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_DCHECK(g_std_function);
7261*6dbdd20aSAndroid Build Coastguard Worker   (*g_std_function)(cb);
7262*6dbdd20aSAndroid Build Coastguard Worker }
7263*6dbdd20aSAndroid Build Coastguard Worker 
7264*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
7265*6dbdd20aSAndroid Build Coastguard Worker 
TEST(PerfettoApiInitTest,AsyncSocket)7266*6dbdd20aSAndroid Build Coastguard Worker TEST(PerfettoApiInitTest, AsyncSocket) {
7267*6dbdd20aSAndroid Build Coastguard Worker   auto system_service = perfetto::test::SystemService::Start();
7268*6dbdd20aSAndroid Build Coastguard Worker   // If the system backend isn't supported, skip
7269*6dbdd20aSAndroid Build Coastguard Worker   if (!system_service.valid()) {
7270*6dbdd20aSAndroid Build Coastguard Worker     GTEST_SKIP();
7271*6dbdd20aSAndroid Build Coastguard Worker   }
7272*6dbdd20aSAndroid Build Coastguard Worker 
7273*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::Tracing::IsInitialized());
7274*6dbdd20aSAndroid Build Coastguard Worker 
7275*6dbdd20aSAndroid Build Coastguard Worker   perfetto::CreateSocketCallback socket_callback;
7276*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent create_socket_called;
7277*6dbdd20aSAndroid Build Coastguard Worker 
7278*6dbdd20aSAndroid Build Coastguard Worker   TracingInitArgs args;
7279*6dbdd20aSAndroid Build Coastguard Worker   args.backends = perfetto::kSystemBackend;
7280*6dbdd20aSAndroid Build Coastguard Worker   args.tracing_policy = g_test_tracing_policy;
7281*6dbdd20aSAndroid Build Coastguard Worker   args.create_socket_async = &CallCreateSocketFunction;
7282*6dbdd20aSAndroid Build Coastguard Worker   SetCreateSocketFunction([&socket_callback, &create_socket_called](
7283*6dbdd20aSAndroid Build Coastguard Worker                               perfetto::CreateSocketCallback cb) {
7284*6dbdd20aSAndroid Build Coastguard Worker     socket_callback = cb;
7285*6dbdd20aSAndroid Build Coastguard Worker     create_socket_called.Notify();
7286*6dbdd20aSAndroid Build Coastguard Worker   });
7287*6dbdd20aSAndroid Build Coastguard Worker 
7288*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::Initialize(args);
7289*6dbdd20aSAndroid Build Coastguard Worker   create_socket_called.Wait();
7290*6dbdd20aSAndroid Build Coastguard Worker 
7291*6dbdd20aSAndroid Build Coastguard Worker   int fd = ConnectUnixSocket();
7292*6dbdd20aSAndroid Build Coastguard Worker   socket_callback(fd);
7293*6dbdd20aSAndroid Build Coastguard Worker 
7294*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
7295*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(perfetto::Tracing::NewTrace(perfetto::kSystemBackend)
7296*6dbdd20aSAndroid Build Coastguard Worker                   ->QueryServiceStateBlocking()
7297*6dbdd20aSAndroid Build Coastguard Worker                   .success);
7298*6dbdd20aSAndroid Build Coastguard Worker 
7299*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::ResetForTesting();
7300*6dbdd20aSAndroid Build Coastguard Worker   ResetCreateSocketFunction();
7301*6dbdd20aSAndroid Build Coastguard Worker }
7302*6dbdd20aSAndroid Build Coastguard Worker 
TEST(PerfettoApiInitTest,AsyncSocketDisconnect)7303*6dbdd20aSAndroid Build Coastguard Worker TEST(PerfettoApiInitTest, AsyncSocketDisconnect) {
7304*6dbdd20aSAndroid Build Coastguard Worker   auto system_service = perfetto::test::SystemService::Start();
7305*6dbdd20aSAndroid Build Coastguard Worker   // If the system backend isn't supported, skip
7306*6dbdd20aSAndroid Build Coastguard Worker   if (!system_service.valid()) {
7307*6dbdd20aSAndroid Build Coastguard Worker     GTEST_SKIP();
7308*6dbdd20aSAndroid Build Coastguard Worker   }
7309*6dbdd20aSAndroid Build Coastguard Worker 
7310*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::Tracing::IsInitialized());
7311*6dbdd20aSAndroid Build Coastguard Worker 
7312*6dbdd20aSAndroid Build Coastguard Worker   perfetto::CreateSocketCallback socket_callback;
7313*6dbdd20aSAndroid Build Coastguard Worker   testing::MockFunction<CreateSocketFunction> mock_create_socket;
7314*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent create_socket_called1, create_socket_called2;
7315*6dbdd20aSAndroid Build Coastguard Worker 
7316*6dbdd20aSAndroid Build Coastguard Worker   TracingInitArgs args;
7317*6dbdd20aSAndroid Build Coastguard Worker   args.backends = perfetto::kSystemBackend;
7318*6dbdd20aSAndroid Build Coastguard Worker   args.tracing_policy = g_test_tracing_policy;
7319*6dbdd20aSAndroid Build Coastguard Worker   args.create_socket_async = &CallCreateSocketFunction;
7320*6dbdd20aSAndroid Build Coastguard Worker   SetCreateSocketFunction(mock_create_socket.AsStdFunction());
7321*6dbdd20aSAndroid Build Coastguard Worker 
7322*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_CALL(mock_create_socket, Call)
7323*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([&socket_callback, &create_socket_called1](
7324*6dbdd20aSAndroid Build Coastguard Worker                            perfetto::CreateSocketCallback cb) {
7325*6dbdd20aSAndroid Build Coastguard Worker         socket_callback = cb;
7326*6dbdd20aSAndroid Build Coastguard Worker         create_socket_called1.Notify();
7327*6dbdd20aSAndroid Build Coastguard Worker       }))
7328*6dbdd20aSAndroid Build Coastguard Worker       .WillOnce(Invoke([&socket_callback, &create_socket_called2](
7329*6dbdd20aSAndroid Build Coastguard Worker                            perfetto::CreateSocketCallback cb) {
7330*6dbdd20aSAndroid Build Coastguard Worker         socket_callback = cb;
7331*6dbdd20aSAndroid Build Coastguard Worker         create_socket_called2.Notify();
7332*6dbdd20aSAndroid Build Coastguard Worker       }));
7333*6dbdd20aSAndroid Build Coastguard Worker 
7334*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::Initialize(args);
7335*6dbdd20aSAndroid Build Coastguard Worker   create_socket_called1.Wait();
7336*6dbdd20aSAndroid Build Coastguard Worker   int fd = ConnectUnixSocket();
7337*6dbdd20aSAndroid Build Coastguard Worker   socket_callback(fd);
7338*6dbdd20aSAndroid Build Coastguard Worker 
7339*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
7340*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(perfetto::Tracing::NewTrace(perfetto::kSystemBackend)
7341*6dbdd20aSAndroid Build Coastguard Worker                   ->QueryServiceStateBlocking()
7342*6dbdd20aSAndroid Build Coastguard Worker                   .success);
7343*6dbdd20aSAndroid Build Coastguard Worker 
7344*6dbdd20aSAndroid Build Coastguard Worker   // Restart the system service. This will cause the producer and consumer to
7345*6dbdd20aSAndroid Build Coastguard Worker   // disconnect and reconnect. The create_socket_async function should be called
7346*6dbdd20aSAndroid Build Coastguard Worker   // for the second time.
7347*6dbdd20aSAndroid Build Coastguard Worker   system_service.Restart();
7348*6dbdd20aSAndroid Build Coastguard Worker   create_socket_called2.Wait();
7349*6dbdd20aSAndroid Build Coastguard Worker   fd = ConnectUnixSocket();
7350*6dbdd20aSAndroid Build Coastguard Worker   socket_callback(fd);
7351*6dbdd20aSAndroid Build Coastguard Worker 
7352*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
7353*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(perfetto::Tracing::NewTrace(perfetto::kSystemBackend)
7354*6dbdd20aSAndroid Build Coastguard Worker                   ->QueryServiceStateBlocking()
7355*6dbdd20aSAndroid Build Coastguard Worker                   .success);
7356*6dbdd20aSAndroid Build Coastguard Worker 
7357*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::ResetForTesting();
7358*6dbdd20aSAndroid Build Coastguard Worker   ResetCreateSocketFunction();
7359*6dbdd20aSAndroid Build Coastguard Worker }
7360*6dbdd20aSAndroid Build Coastguard Worker 
TEST(PerfettoApiInitTest,AsyncSocketStartupTracing)7361*6dbdd20aSAndroid Build Coastguard Worker TEST(PerfettoApiInitTest, AsyncSocketStartupTracing) {
7362*6dbdd20aSAndroid Build Coastguard Worker   auto system_service = perfetto::test::SystemService::Start();
7363*6dbdd20aSAndroid Build Coastguard Worker   // If the system backend isn't supported, skip
7364*6dbdd20aSAndroid Build Coastguard Worker   if (!system_service.valid()) {
7365*6dbdd20aSAndroid Build Coastguard Worker     GTEST_SKIP();
7366*6dbdd20aSAndroid Build Coastguard Worker   }
7367*6dbdd20aSAndroid Build Coastguard Worker 
7368*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_FALSE(perfetto::Tracing::IsInitialized());
7369*6dbdd20aSAndroid Build Coastguard Worker 
7370*6dbdd20aSAndroid Build Coastguard Worker   perfetto::CreateSocketCallback socket_callback;
7371*6dbdd20aSAndroid Build Coastguard Worker   WaitableTestEvent create_socket_called;
7372*6dbdd20aSAndroid Build Coastguard Worker 
7373*6dbdd20aSAndroid Build Coastguard Worker   TracingInitArgs args;
7374*6dbdd20aSAndroid Build Coastguard Worker   args.backends = perfetto::kSystemBackend;
7375*6dbdd20aSAndroid Build Coastguard Worker   args.tracing_policy = g_test_tracing_policy;
7376*6dbdd20aSAndroid Build Coastguard Worker   args.create_socket_async = &CallCreateSocketFunction;
7377*6dbdd20aSAndroid Build Coastguard Worker   SetCreateSocketFunction([&socket_callback, &create_socket_called](
7378*6dbdd20aSAndroid Build Coastguard Worker                               perfetto::CreateSocketCallback cb) {
7379*6dbdd20aSAndroid Build Coastguard Worker     socket_callback = cb;
7380*6dbdd20aSAndroid Build Coastguard Worker     create_socket_called.Notify();
7381*6dbdd20aSAndroid Build Coastguard Worker   });
7382*6dbdd20aSAndroid Build Coastguard Worker 
7383*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::Initialize(args);
7384*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Register();
7385*6dbdd20aSAndroid Build Coastguard Worker 
7386*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TraceConfig cfg;
7387*6dbdd20aSAndroid Build Coastguard Worker   cfg.set_duration_ms(500);
7388*6dbdd20aSAndroid Build Coastguard Worker   cfg.add_buffers()->set_size_kb(1024);
7389*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
7390*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_name("track_event");
7391*6dbdd20aSAndroid Build Coastguard Worker 
7392*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::TrackEventConfig te_cfg;
7393*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.add_disabled_categories("*");
7394*6dbdd20aSAndroid Build Coastguard Worker   te_cfg.add_enabled_categories("test");
7395*6dbdd20aSAndroid Build Coastguard Worker   ds_cfg->set_track_event_config_raw(te_cfg.SerializeAsString());
7396*6dbdd20aSAndroid Build Coastguard Worker 
7397*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::SetupStartupTracingOpts opts;
7398*6dbdd20aSAndroid Build Coastguard Worker   opts.backend = perfetto::kSystemBackend;
7399*6dbdd20aSAndroid Build Coastguard Worker   auto startup_session =
7400*6dbdd20aSAndroid Build Coastguard Worker       perfetto::Tracing::SetupStartupTracingBlocking(cfg, std::move(opts));
7401*6dbdd20aSAndroid Build Coastguard Worker 
7402*6dbdd20aSAndroid Build Coastguard Worker   // Emit a significant number of events to write >1 chunk of data.
7403*6dbdd20aSAndroid Build Coastguard Worker   constexpr size_t kNumEvents = 1000;
7404*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumEvents; i++) {
7405*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT("test", "StartupEvent");
7406*6dbdd20aSAndroid Build Coastguard Worker   }
7407*6dbdd20aSAndroid Build Coastguard Worker 
7408*6dbdd20aSAndroid Build Coastguard Worker   // Now proceed with the connection to the service and wait until it completes.
7409*6dbdd20aSAndroid Build Coastguard Worker   int fd = ConnectUnixSocket();
7410*6dbdd20aSAndroid Build Coastguard Worker   socket_callback(fd);
7411*6dbdd20aSAndroid Build Coastguard Worker   perfetto::test::SyncProducers();
7412*6dbdd20aSAndroid Build Coastguard Worker 
7413*6dbdd20aSAndroid Build Coastguard Worker   auto session = perfetto::Tracing::NewTrace(perfetto::kSystemBackend);
7414*6dbdd20aSAndroid Build Coastguard Worker   session->Setup(cfg);
7415*6dbdd20aSAndroid Build Coastguard Worker   session->StartBlocking();
7416*6dbdd20aSAndroid Build Coastguard Worker 
7417*6dbdd20aSAndroid Build Coastguard Worker   // Write even more events, now with connection established.
7418*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumEvents; i++) {
7419*6dbdd20aSAndroid Build Coastguard Worker     TRACE_EVENT_INSTANT("test", "TraceEvent");
7420*6dbdd20aSAndroid Build Coastguard Worker   }
7421*6dbdd20aSAndroid Build Coastguard Worker 
7422*6dbdd20aSAndroid Build Coastguard Worker   perfetto::TrackEvent::Flush();
7423*6dbdd20aSAndroid Build Coastguard Worker   session->StopBlocking();
7424*6dbdd20aSAndroid Build Coastguard Worker 
7425*6dbdd20aSAndroid Build Coastguard Worker   auto raw_trace = session->ReadTraceBlocking();
7426*6dbdd20aSAndroid Build Coastguard Worker   perfetto::protos::gen::Trace parsed_trace;
7427*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_TRUE(parsed_trace.ParseFromArray(raw_trace.data(), raw_trace.size()));
7428*6dbdd20aSAndroid Build Coastguard Worker 
7429*6dbdd20aSAndroid Build Coastguard Worker   size_t n_track_events = 0;
7430*6dbdd20aSAndroid Build Coastguard Worker   for (const auto& packet : parsed_trace.packet()) {
7431*6dbdd20aSAndroid Build Coastguard Worker     if (packet.has_track_event()) {
7432*6dbdd20aSAndroid Build Coastguard Worker       ++n_track_events;
7433*6dbdd20aSAndroid Build Coastguard Worker     }
7434*6dbdd20aSAndroid Build Coastguard Worker   }
7435*6dbdd20aSAndroid Build Coastguard Worker 
7436*6dbdd20aSAndroid Build Coastguard Worker   // Events from both startup and service-initiated sessions should be retained.
7437*6dbdd20aSAndroid Build Coastguard Worker   EXPECT_EQ(n_track_events, kNumEvents * 2);
7438*6dbdd20aSAndroid Build Coastguard Worker 
7439*6dbdd20aSAndroid Build Coastguard Worker   startup_session.reset();
7440*6dbdd20aSAndroid Build Coastguard Worker   session.reset();
7441*6dbdd20aSAndroid Build Coastguard Worker   perfetto::Tracing::ResetForTesting();
7442*6dbdd20aSAndroid Build Coastguard Worker   ResetCreateSocketFunction();
7443*6dbdd20aSAndroid Build Coastguard Worker }
7444*6dbdd20aSAndroid Build Coastguard Worker #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7445*6dbdd20aSAndroid Build Coastguard Worker 
7446*6dbdd20aSAndroid Build Coastguard Worker struct BackendTypeAsString {
operator ()__anonfc73210d0111::BackendTypeAsString7447*6dbdd20aSAndroid Build Coastguard Worker   std::string operator()(
7448*6dbdd20aSAndroid Build Coastguard Worker       const ::testing::TestParamInfo<perfetto::BackendType>& info) const {
7449*6dbdd20aSAndroid Build Coastguard Worker     switch (info.param) {
7450*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::kInProcessBackend:
7451*6dbdd20aSAndroid Build Coastguard Worker         return "InProc";
7452*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::kSystemBackend:
7453*6dbdd20aSAndroid Build Coastguard Worker         return "System";
7454*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::kCustomBackend:
7455*6dbdd20aSAndroid Build Coastguard Worker         return "Custom";
7456*6dbdd20aSAndroid Build Coastguard Worker       case perfetto::kUnspecifiedBackend:
7457*6dbdd20aSAndroid Build Coastguard Worker         return "Unspec";
7458*6dbdd20aSAndroid Build Coastguard Worker     }
7459*6dbdd20aSAndroid Build Coastguard Worker     return nullptr;
7460*6dbdd20aSAndroid Build Coastguard Worker   }
7461*6dbdd20aSAndroid Build Coastguard Worker };
7462*6dbdd20aSAndroid Build Coastguard Worker 
7463*6dbdd20aSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(PerfettoApiTest,
7464*6dbdd20aSAndroid Build Coastguard Worker                          PerfettoApiTest,
7465*6dbdd20aSAndroid Build Coastguard Worker                          ::testing::Values(perfetto::kInProcessBackend,
7466*6dbdd20aSAndroid Build Coastguard Worker                                            perfetto::kSystemBackend),
7467*6dbdd20aSAndroid Build Coastguard Worker                          BackendTypeAsString());
7468*6dbdd20aSAndroid Build Coastguard Worker 
7469*6dbdd20aSAndroid Build Coastguard Worker // In-process backend doesn't support startup tracing.
7470*6dbdd20aSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(PerfettoStartupTracingApiTest,
7471*6dbdd20aSAndroid Build Coastguard Worker                          PerfettoStartupTracingApiTest,
7472*6dbdd20aSAndroid Build Coastguard Worker                          ::testing::Values(perfetto::kSystemBackend),
7473*6dbdd20aSAndroid Build Coastguard Worker                          BackendTypeAsString());
7474*6dbdd20aSAndroid Build Coastguard Worker 
7475*6dbdd20aSAndroid Build Coastguard Worker class PerfettoApiEnvironment : public ::testing::Environment {
7476*6dbdd20aSAndroid Build Coastguard Worker  public:
TearDown()7477*6dbdd20aSAndroid Build Coastguard Worker   void TearDown() override {
7478*6dbdd20aSAndroid Build Coastguard Worker     // Test shutting down Perfetto only when all other tests have been run and
7479*6dbdd20aSAndroid Build Coastguard Worker     // no more tracing code will be executed.
7480*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_CHECK(!perfetto::Tracing::IsInitialized());
7481*6dbdd20aSAndroid Build Coastguard Worker     perfetto::TracingInitArgs args;
7482*6dbdd20aSAndroid Build Coastguard Worker     args.backends = perfetto::kInProcessBackend;
7483*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Tracing::Initialize(args);
7484*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Tracing::Shutdown();
7485*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_CHECK(!perfetto::Tracing::IsInitialized());
7486*6dbdd20aSAndroid Build Coastguard Worker     // Shutting down again is a no-op.
7487*6dbdd20aSAndroid Build Coastguard Worker     perfetto::Tracing::Shutdown();
7488*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_CHECK(!perfetto::Tracing::IsInitialized());
7489*6dbdd20aSAndroid Build Coastguard Worker   }
7490*6dbdd20aSAndroid Build Coastguard Worker };
7491*6dbdd20aSAndroid Build Coastguard Worker 
7492*6dbdd20aSAndroid Build Coastguard Worker int PERFETTO_UNUSED initializer =
__anonfc73210d8602null7493*6dbdd20aSAndroid Build Coastguard Worker     perfetto::integration_tests::RegisterApiIntegrationTestInitializer([] {
7494*6dbdd20aSAndroid Build Coastguard Worker       ::testing::AddGlobalTestEnvironment(new PerfettoApiEnvironment);
7495*6dbdd20aSAndroid Build Coastguard Worker     });
7496*6dbdd20aSAndroid Build Coastguard Worker 
7497*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
7498*6dbdd20aSAndroid Build Coastguard Worker 
7499*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(CustomDataSource);
7500*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource);
7501*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource2);
7502*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(TestIncrementalDataSource,
7503*6dbdd20aSAndroid Build Coastguard Worker                                             TestIncrementalDataSourceTraits);
7504*6dbdd20aSAndroid Build Coastguard Worker 
7505*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(CustomDataSource);
7506*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource);
7507*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(MockDataSource2);
7508*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(TestIncrementalDataSource,
7509*6dbdd20aSAndroid Build Coastguard Worker                                            TestIncrementalDataSourceTraits);
7510