• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package dev.perfetto.sdk.test;
18 
19 import static dev.perfetto.sdk.PerfettoTrace.Category;
20 import dev.perfetto.sdk.*;
21 
22 import static com.google.common.truth.Truth.assertThat;
23 
24 import static perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo.LatencyComponentType.COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH;
25 import static perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo.LatencyComponentType.COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL;
26 
27 import android.util.ArraySet;
28 
29 import android.os.Process;
30 
31 import androidx.test.InstrumentationRegistry;
32 import androidx.test.ext.junit.runners.AndroidJUnit4;
33 
34 import org.junit.Before;
35 import org.junit.Ignore;
36 import org.junit.Rule;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 
40 import perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo;
41 import perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo.ComponentInfo;
42 import perfetto.protos.DataSourceConfigOuterClass.DataSourceConfig;
43 import perfetto.protos.DebugAnnotationOuterClass.DebugAnnotation;
44 import perfetto.protos.DebugAnnotationOuterClass.DebugAnnotationName;
45 import perfetto.protos.InternedDataOuterClass.InternedData;
46 import perfetto.protos.SourceLocationOuterClass.SourceLocation;
47 import perfetto.protos.TraceConfigOuterClass.TraceConfig;
48 import perfetto.protos.TraceConfigOuterClass.TraceConfig.BufferConfig;
49 import perfetto.protos.TraceConfigOuterClass.TraceConfig.DataSource;
50 import perfetto.protos.TraceConfigOuterClass.TraceConfig.TriggerConfig;
51 import perfetto.protos.TraceConfigOuterClass.TraceConfig.TriggerConfig.Trigger;
52 import perfetto.protos.TraceOuterClass.Trace;
53 import perfetto.protos.TracePacketOuterClass.TracePacket;
54 import perfetto.protos.TrackDescriptorOuterClass.TrackDescriptor;
55 import perfetto.protos.TrackEventConfigOuterClass.TrackEventConfig;
56 import perfetto.protos.TrackEventOuterClass.EventCategory;
57 import perfetto.protos.TrackEventOuterClass.EventName;
58 import perfetto.protos.TrackEventOuterClass.TrackEvent;
59 
60 import java.util.List;
61 import java.util.Set;
62 import java.util.concurrent.CountDownLatch;
63 import java.util.concurrent.TimeUnit;
64 
65 /**
66  * This class is used to test the native tracing support. Run this test
67  * while tracing on the emulator and then run traceview to view the trace.
68  */
69 @RunWith(AndroidJUnit4.class)
70 public class PerfettoTraceTest {
71     static {
72         System.loadLibrary("perfetto_jni_lib");
73     }
74 
75     private static final String TAG = "PerfettoTraceTest";
76     private static final String FOO = "foo";
77     private static final String BAR = "bar";
78     private static final String TEXT_ABOVE_4K_SIZE =
79             new String(new char[8192]).replace('\0', 'a');
80 
81     private static final Category FOO_CATEGORY = new Category(FOO);
82     private static final int MESSAGE = 1234567;
83     private static final int MESSAGE_COUNT = 3;
84 
85     private final Set<String> mCategoryNames = new ArraySet<>();
86     private final Set<String> mEventNames = new ArraySet<>();
87     private final Set<String> mDebugAnnotationNames = new ArraySet<>();
88     private final Set<String> mTrackNames = new ArraySet<>();
89 
90     @Before
setUp()91     public void setUp() {
92         PerfettoTrace.register(true);
93         // 'var unused' suppress error-prone warning
94         var unused = FOO_CATEGORY.register();
95 
96         mCategoryNames.clear();
97         mEventNames.clear();
98         mDebugAnnotationNames.clear();
99         mTrackNames.clear();
100     }
101 
102     @Test
testDebugAnnotations()103     public void testDebugAnnotations() throws Exception {
104         TraceConfig traceConfig = getTraceConfig(FOO);
105 
106         PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
107 
108         PerfettoTrace.instant(FOO_CATEGORY, "event")
109                 .setFlow(2)
110                 .setTerminatingFlow(3)
111                 .addArg("long_val", 10000000000L)
112                 .addArg("bool_val", true)
113                 .addArg("double_val", 3.14)
114                 .addArg("string_val", FOO)
115                 .emit();
116 
117         byte[] traceBytes = session.close();
118 
119         Trace trace = Trace.parseFrom(traceBytes);
120 
121         boolean hasTrackEvent = false;
122         boolean hasDebugAnnotations = false;
123         for (TracePacket packet: trace.getPacketList()) {
124             TrackEvent event;
125             if (packet.hasTrackEvent()) {
126                 hasTrackEvent = true;
127                 event = packet.getTrackEvent();
128 
129                 if (TrackEvent.Type.TYPE_INSTANT.equals(event.getType())
130                         && event.getDebugAnnotationsCount() == 4 && event.getFlowIdsCount() == 1
131                         && event.getTerminatingFlowIdsCount() == 1) {
132                     hasDebugAnnotations = true;
133 
134                     List<DebugAnnotation> annotations = event.getDebugAnnotationsList();
135 
136                     assertThat(annotations.get(0).getIntValue()).isEqualTo(10000000000L);
137                     assertThat(annotations.get(1).getBoolValue()).isTrue();
138                     assertThat(annotations.get(2).getDoubleValue()).isEqualTo(3.14);
139                     assertThat(annotations.get(3).getStringValue()).isEqualTo(FOO);
140                 }
141             }
142 
143             collectInternedData(packet);
144         }
145 
146         assertThat(hasTrackEvent).isTrue();
147         assertThat(hasDebugAnnotations).isTrue();
148         assertThat(mCategoryNames).contains(FOO);
149 
150         assertThat(mDebugAnnotationNames).contains("long_val");
151         assertThat(mDebugAnnotationNames).contains("bool_val");
152         assertThat(mDebugAnnotationNames).contains("double_val");
153         assertThat(mDebugAnnotationNames).contains("string_val");
154     }
155 
156     @Test
testNamedTrack()157     public void testNamedTrack() throws Exception {
158         TraceConfig traceConfig = getTraceConfig(FOO);
159 
160         PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
161 
162         PerfettoTrace.begin(FOO_CATEGORY, "event")
163                 .usingNamedTrack(PerfettoTrace.getProcessTrackUuid(), FOO)
164                 .emit();
165 
166 
167         PerfettoTrace.end(FOO_CATEGORY)
168                 .usingNamedTrack(PerfettoTrace.getThreadTrackUuid(Process.myTid()), "bar")
169                 .emit();
170 
171         Trace trace = Trace.parseFrom(session.close());
172 
173         boolean hasTrackEvent = false;
174         boolean hasTrackUuid = false;
175         for (TracePacket packet: trace.getPacketList()) {
176             TrackEvent event;
177             if (packet.hasTrackEvent()) {
178                 hasTrackEvent = true;
179                 event = packet.getTrackEvent();
180 
181                 if (TrackEvent.Type.TYPE_SLICE_BEGIN.equals(event.getType())
182                         && event.hasTrackUuid()) {
183                     hasTrackUuid = true;
184                 }
185 
186                 if (TrackEvent.Type.TYPE_SLICE_END.equals(event.getType())
187                         && event.hasTrackUuid()) {
188                     hasTrackUuid &= true;
189                 }
190             }
191 
192             collectInternedData(packet);
193             collectTrackNames(packet);
194         }
195 
196         assertThat(hasTrackEvent).isTrue();
197         assertThat(hasTrackUuid).isTrue();
198         assertThat(mCategoryNames).contains(FOO);
199         assertThat(mTrackNames).contains(FOO);
200         assertThat(mTrackNames).contains("bar");
201     }
202 
203     @Test
testProcessThreadNamedTrack()204     public void testProcessThreadNamedTrack() throws Exception {
205         TraceConfig traceConfig = getTraceConfig(FOO);
206 
207         PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
208 
209         PerfettoTrace.begin(FOO_CATEGORY, "event")
210                 .usingProcessNamedTrack(FOO)
211                 .emit();
212 
213 
214         PerfettoTrace.end(FOO_CATEGORY)
215                 .usingThreadNamedTrack(Process.myTid(), "bar")
216                 .emit();
217 
218         Trace trace = Trace.parseFrom(session.close());
219 
220         boolean hasTrackEvent = false;
221         boolean hasTrackUuid = false;
222         for (TracePacket packet: trace.getPacketList()) {
223             TrackEvent event;
224             if (packet.hasTrackEvent()) {
225                 hasTrackEvent = true;
226                 event = packet.getTrackEvent();
227 
228                 if (TrackEvent.Type.TYPE_SLICE_BEGIN.equals(event.getType())
229                         && event.hasTrackUuid()) {
230                     hasTrackUuid = true;
231                 }
232 
233                 if (TrackEvent.Type.TYPE_SLICE_END.equals(event.getType())
234                         && event.hasTrackUuid()) {
235                     hasTrackUuid &= true;
236                 }
237             }
238 
239             collectInternedData(packet);
240             collectTrackNames(packet);
241         }
242 
243         assertThat(hasTrackEvent).isTrue();
244         assertThat(hasTrackUuid).isTrue();
245         assertThat(mCategoryNames).contains(FOO);
246         assertThat(mTrackNames).contains(FOO);
247         assertThat(mTrackNames).contains("bar");
248     }
249 
250     @Test
testCounterSimple()251     public void testCounterSimple() throws Exception {
252         TraceConfig traceConfig = getTraceConfig(FOO);
253 
254         PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
255 
256         PerfettoTrace.counter(FOO_CATEGORY, 16, FOO).emit();
257 
258         PerfettoTrace.counter(FOO_CATEGORY, 3.14, "bar").emit();
259 
260         Trace trace = Trace.parseFrom(session.close());
261 
262         boolean hasTrackEvent = false;
263         boolean hasCounterValue = false;
264         boolean hasDoubleCounterValue = false;
265         for (TracePacket packet: trace.getPacketList()) {
266             TrackEvent event;
267             if (packet.hasTrackEvent()) {
268                 hasTrackEvent = true;
269                 event = packet.getTrackEvent();
270 
271                 if (TrackEvent.Type.TYPE_COUNTER.equals(event.getType())
272                         && event.getCounterValue() == 16) {
273                     hasCounterValue = true;
274                 }
275 
276                 if (TrackEvent.Type.TYPE_COUNTER.equals(event.getType())
277                         && event.getDoubleCounterValue() == 3.14) {
278                     hasDoubleCounterValue = true;
279                 }
280             }
281 
282             collectTrackNames(packet);
283         }
284 
285         assertThat(hasTrackEvent).isTrue();
286         assertThat(hasCounterValue).isTrue();
287         assertThat(hasDoubleCounterValue).isTrue();
288         assertThat(mTrackNames).contains(FOO);
289         assertThat(mTrackNames).contains(BAR);
290     }
291 
292     @Test
testCounter()293     public void testCounter() throws Exception {
294         TraceConfig traceConfig = getTraceConfig(FOO);
295 
296         PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
297 
298         PerfettoTrace.counter(FOO_CATEGORY, 16)
299                 .usingCounterTrack(PerfettoTrace.getProcessTrackUuid(), FOO).emit();
300 
301         PerfettoTrace.counter(FOO_CATEGORY, 3.14)
302                 .usingCounterTrack(PerfettoTrace.getThreadTrackUuid(Process.myTid()),
303                                    "bar").emit();
304 
305         Trace trace = Trace.parseFrom(session.close());
306 
307         boolean hasTrackEvent = false;
308         boolean hasCounterValue = false;
309         boolean hasDoubleCounterValue = false;
310         for (TracePacket packet: trace.getPacketList()) {
311             TrackEvent event;
312             if (packet.hasTrackEvent()) {
313                 hasTrackEvent = true;
314                 event = packet.getTrackEvent();
315 
316                 if (TrackEvent.Type.TYPE_COUNTER.equals(event.getType())
317                         && event.getCounterValue() == 16) {
318                     hasCounterValue = true;
319                 }
320 
321                 if (TrackEvent.Type.TYPE_COUNTER.equals(event.getType())
322                         && event.getDoubleCounterValue() == 3.14) {
323                     hasDoubleCounterValue = true;
324                 }
325             }
326 
327             collectTrackNames(packet);
328         }
329 
330         assertThat(hasTrackEvent).isTrue();
331         assertThat(hasCounterValue).isTrue();
332         assertThat(hasDoubleCounterValue).isTrue();
333         assertThat(mTrackNames).contains(FOO);
334         assertThat(mTrackNames).contains("bar");
335     }
336 
337     @Test
testProcessThreadCounter()338     public void testProcessThreadCounter() throws Exception {
339         TraceConfig traceConfig = getTraceConfig(FOO);
340 
341         PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
342 
343         PerfettoTrace.counter(FOO_CATEGORY, 16).usingProcessCounterTrack(FOO).emit();
344 
345         PerfettoTrace.counter(FOO_CATEGORY, 3.14)
346                 .usingThreadCounterTrack(Process.myTid(), "bar").emit();
347 
348         Trace trace = Trace.parseFrom(session.close());
349 
350         boolean hasTrackEvent = false;
351         boolean hasCounterValue = false;
352         boolean hasDoubleCounterValue = false;
353         for (TracePacket packet: trace.getPacketList()) {
354             TrackEvent event;
355             if (packet.hasTrackEvent()) {
356                 hasTrackEvent = true;
357                 event = packet.getTrackEvent();
358 
359                 if (TrackEvent.Type.TYPE_COUNTER.equals(event.getType())
360                         && event.getCounterValue() == 16) {
361                     hasCounterValue = true;
362                 }
363 
364                 if (TrackEvent.Type.TYPE_COUNTER.equals(event.getType())
365                         && event.getDoubleCounterValue() == 3.14) {
366                     hasDoubleCounterValue = true;
367                 }
368             }
369 
370             collectTrackNames(packet);
371         }
372 
373         assertThat(hasTrackEvent).isTrue();
374         assertThat(hasCounterValue).isTrue();
375         assertThat(hasDoubleCounterValue).isTrue();
376         assertThat(mTrackNames).contains(FOO);
377         assertThat(mTrackNames).contains("bar");
378     }
379 
380     @Test
testProto()381     public void testProto() throws Exception {
382         TraceConfig traceConfig = getTraceConfig(FOO);
383 
384         PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
385 
386         PerfettoTrace.instant(FOO_CATEGORY, "event_proto")
387                 .beginProto()
388                 .beginNested(33L)
389                 .addField(4L, 2L)
390                 .addField(3, "ActivityManagerService.java:11489")
391                 .endNested()
392                 .addField(2001, "AIDL::IActivityManager")
393                 .endProto()
394                 .emit();
395 
396         byte[] traceBytes = session.close();
397 
398         Trace trace = Trace.parseFrom(traceBytes);
399 
400         boolean hasTrackEvent = false;
401         boolean hasSourceLocation = false;
402         for (TracePacket packet: trace.getPacketList()) {
403             TrackEvent event;
404             if (packet.hasTrackEvent()) {
405                 hasTrackEvent = true;
406                 event = packet.getTrackEvent();
407 
408                 if (TrackEvent.Type.TYPE_INSTANT.equals(event.getType())
409                         && event.hasSourceLocation()) {
410                     SourceLocation loc = event.getSourceLocation();
411                     if ("ActivityManagerService.java:11489".equals(loc.getFunctionName())
412                             && loc.getLineNumber() == 2) {
413                         hasSourceLocation = true;
414                     }
415                 }
416             }
417 
418             collectInternedData(packet);
419         }
420 
421         assertThat(hasTrackEvent).isTrue();
422         assertThat(hasSourceLocation).isTrue();
423         assertThat(mCategoryNames).contains(FOO);
424     }
425 
426     @Test
testProtoWithSlowPath()427     public void testProtoWithSlowPath() throws Exception {
428         TraceConfig traceConfig = getTraceConfig(FOO);
429 
430         PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
431 
432         PerfettoTrace.instant(FOO_CATEGORY, "event_proto")
433                 .beginProto()
434                 .beginNested(33L)
435                 .addField(4L, 2L)
436                 .addField(3, TEXT_ABOVE_4K_SIZE)
437                 .endNested()
438                 .addField(2001, "AIDL::IActivityManager")
439                 .endProto()
440                 .emit();
441 
442         byte[] traceBytes = session.close();
443 
444         Trace trace = Trace.parseFrom(traceBytes);
445 
446         boolean hasTrackEvent = false;
447         boolean hasSourceLocation = false;
448         for (TracePacket packet: trace.getPacketList()) {
449             TrackEvent event;
450             if (packet.hasTrackEvent()) {
451                 hasTrackEvent = true;
452                 event = packet.getTrackEvent();
453 
454                 if (TrackEvent.Type.TYPE_INSTANT.equals(event.getType())
455                         && event.hasSourceLocation()) {
456                     SourceLocation loc = event.getSourceLocation();
457                     if (TEXT_ABOVE_4K_SIZE.equals(loc.getFunctionName())
458                             && loc.getLineNumber() == 2) {
459                         hasSourceLocation = true;
460                     }
461                 }
462             }
463 
464             collectInternedData(packet);
465         }
466 
467         assertThat(hasTrackEvent).isTrue();
468         assertThat(hasSourceLocation).isTrue();
469         assertThat(mCategoryNames).contains(FOO);
470     }
471 
472     @Test
testProtoNested()473     public void testProtoNested() throws Exception {
474         TraceConfig traceConfig = getTraceConfig(FOO);
475 
476         PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
477 
478         PerfettoTrace.instant(FOO_CATEGORY, "event_proto_nested")
479                 .beginProto()
480                 .beginNested(29L)
481                 .beginNested(4L)
482                 .addField(1L, 2)
483                 .addField(2L, 20000)
484                 .endNested()
485                 .beginNested(4L)
486                 .addField(1L, 1)
487                 .addField(2L, 40000)
488                 .endNested()
489                 .endNested()
490                 .endProto()
491                 .emit();
492 
493         byte[] traceBytes = session.close();
494 
495         Trace trace = Trace.parseFrom(traceBytes);
496 
497         boolean hasTrackEvent = false;
498         boolean hasChromeLatencyInfo = false;
499 
500         for (TracePacket packet: trace.getPacketList()) {
501             TrackEvent event;
502             if (packet.hasTrackEvent()) {
503                 hasTrackEvent = true;
504                 event = packet.getTrackEvent();
505 
506                 if (TrackEvent.Type.TYPE_INSTANT.equals(event.getType())
507                         && event.hasChromeLatencyInfo()) {
508                     ChromeLatencyInfo latencyInfo = event.getChromeLatencyInfo();
509                     if (latencyInfo.getComponentInfoCount() == 2) {
510                         hasChromeLatencyInfo = true;
511                         ComponentInfo cmpInfo1 = latencyInfo.getComponentInfo(0);
512                         assertThat(cmpInfo1.getComponentType())
513                                 .isEqualTo(COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL);
514                         assertThat(cmpInfo1.getTimeUs()).isEqualTo(20000);
515 
516                         ComponentInfo cmpInfo2 = latencyInfo.getComponentInfo(1);
517                         assertThat(cmpInfo2.getComponentType())
518                                 .isEqualTo(COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH);
519                         assertThat(cmpInfo2.getTimeUs()).isEqualTo(40000);
520                     }
521                 }
522             }
523 
524             collectInternedData(packet);
525         }
526 
527         assertThat(hasTrackEvent).isTrue();
528         assertThat(hasChromeLatencyInfo).isTrue();
529         assertThat(mCategoryNames).contains(FOO);
530     }
531 
532     @Test
testActivateTrigger()533     public void testActivateTrigger() throws Exception {
534         TraceConfig traceConfig = getTriggerTraceConfig(FOO, FOO);
535 
536         PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
537 
538         PerfettoTrace.instant(FOO_CATEGORY, "event_trigger").emit();
539 
540         PerfettoTrace.activateTrigger(FOO, 1000);
541 
542         byte[] traceBytes = session.close();
543 
544         Trace trace = Trace.parseFrom(traceBytes);
545 
546         boolean hasTrackEvent = false;
547         boolean hasChromeLatencyInfo = false;
548 
549         for (TracePacket packet: trace.getPacketList()) {
550             TrackEvent event;
551             if (packet.hasTrackEvent()) {
552                 hasTrackEvent = true;
553             }
554 
555             collectInternedData(packet);
556         }
557 
558         assertThat(mCategoryNames).contains(FOO);
559     }
560 
561     @Test
testRegister()562     public void testRegister() throws Exception {
563         TraceConfig traceConfig = getTraceConfig(BAR);
564 
565         Category barCategory = new Category(BAR);
566         PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
567 
568         PerfettoTrace.instant(barCategory, "event")
569                 .addArg("before", 1)
570                 .emit();
571         // 'var unused' suppress error-prone warning
572         var unused = barCategory.register();
573 
574         PerfettoTrace.instant(barCategory, "event")
575                 .addArg("after", 1)
576                 .emit();
577 
578         byte[] traceBytes = session.close();
579 
580         Trace trace = Trace.parseFrom(traceBytes);
581 
582         boolean hasTrackEvent = false;
583         for (TracePacket packet: trace.getPacketList()) {
584             TrackEvent event;
585             if (packet.hasTrackEvent()) {
586                 hasTrackEvent = true;
587                 event = packet.getTrackEvent();
588             }
589 
590             collectInternedData(packet);
591         }
592 
593         assertThat(hasTrackEvent).isTrue();
594         assertThat(mCategoryNames).contains(BAR);
595 
596         assertThat(mDebugAnnotationNames).contains("after");
597         assertThat(mDebugAnnotationNames).doesNotContain("before");
598     }
599 
getTrackEvent(Trace trace, int idx)600     private TrackEvent getTrackEvent(Trace trace, int idx) {
601         int curIdx = 0;
602         for (TracePacket packet: trace.getPacketList()) {
603             if (packet.hasTrackEvent()) {
604                 if (curIdx++ == idx) {
605                     return packet.getTrackEvent();
606                 }
607             }
608         }
609 
610         return null;
611     }
612 
getTraceConfig(String cat)613     private TraceConfig getTraceConfig(String cat) {
614         BufferConfig bufferConfig = BufferConfig.newBuilder().setSizeKb(1024).build();
615         TrackEventConfig trackEventConfig = TrackEventConfig
616                 .newBuilder()
617                 .addEnabledCategories(cat)
618                 .build();
619         DataSourceConfig dsConfig = DataSourceConfig
620                 .newBuilder()
621                 .setName("track_event")
622                 .setTargetBuffer(0)
623                 .setTrackEventConfig(trackEventConfig)
624                 .build();
625         DataSource ds = DataSource.newBuilder().setConfig(dsConfig).build();
626         TraceConfig traceConfig = TraceConfig
627                 .newBuilder()
628                 .addBuffers(bufferConfig)
629                 .addDataSources(ds)
630                 .build();
631         return traceConfig;
632     }
633 
getTriggerTraceConfig(String cat, String triggerName)634     private TraceConfig getTriggerTraceConfig(String cat, String triggerName) {
635         BufferConfig bufferConfig = BufferConfig.newBuilder().setSizeKb(1024).build();
636         TrackEventConfig trackEventConfig = TrackEventConfig
637                 .newBuilder()
638                 .addEnabledCategories(cat)
639                 .build();
640         DataSourceConfig dsConfig = DataSourceConfig
641                 .newBuilder()
642                 .setName("track_event")
643                 .setTargetBuffer(0)
644                 .setTrackEventConfig(trackEventConfig)
645                 .build();
646         DataSource ds = DataSource.newBuilder().setConfig(dsConfig).build();
647         Trigger trigger = Trigger.newBuilder().setName(triggerName).build();
648         TriggerConfig triggerConfig = TriggerConfig
649                 .newBuilder()
650                 .setTriggerMode(TriggerConfig.TriggerMode.STOP_TRACING)
651                 .setTriggerTimeoutMs(1000)
652                 .addTriggers(trigger)
653                 .build();
654         TraceConfig traceConfig = TraceConfig
655                 .newBuilder()
656                 .addBuffers(bufferConfig)
657                 .addDataSources(ds)
658                 .setTriggerConfig(triggerConfig)
659                 .build();
660         return traceConfig;
661     }
662 
collectInternedData(TracePacket packet)663     private void collectInternedData(TracePacket packet) {
664         if (!packet.hasInternedData()) {
665             return;
666         }
667 
668         InternedData data = packet.getInternedData();
669 
670         for (EventCategory cat : data.getEventCategoriesList()) {
671             mCategoryNames.add(cat.getName());
672         }
673         for (EventName ev : data.getEventNamesList()) {
674             mEventNames.add(ev.getName());
675         }
676         for (DebugAnnotationName dbg : data.getDebugAnnotationNamesList()) {
677             mDebugAnnotationNames.add(dbg.getName());
678         }
679     }
680 
collectTrackNames(TracePacket packet)681     private void collectTrackNames(TracePacket packet) {
682         if (!packet.hasTrackDescriptor()) {
683             return;
684         }
685         TrackDescriptor desc = packet.getTrackDescriptor();
686         mTrackNames.add(desc.getName());
687     }
688 }
689