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