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 android.os; 18 19 import com.android.internal.ravenwood.RavenwoodEnvironment; 20 21 import dalvik.annotation.optimization.CriticalNative; 22 import dalvik.annotation.optimization.FastNative; 23 24 import libcore.util.NativeAllocationRegistry; 25 26 import java.util.ArrayList; 27 import java.util.List; 28 import java.util.concurrent.atomic.AtomicLong; 29 import java.util.function.Supplier; 30 31 /** 32 * Holds extras to be passed to Perfetto track events in {@link PerfettoTrace}. 33 * 34 * @hide 35 */ 36 @android.ravenwood.annotation.RavenwoodKeepWholeClass 37 public final class PerfettoTrackEventExtra { 38 private static final boolean DEBUG = false; 39 private static final int DEFAULT_EXTRA_CACHE_SIZE = 5; 40 private static final Builder NO_OP_BUILDER = new Builder(/* extra= */ null, /* isCategoryEnabled= */ false); 41 private static final ThreadLocal<PerfettoTrackEventExtra> sTrackEventExtra = 42 new ThreadLocal<PerfettoTrackEventExtra>() { 43 @Override 44 protected PerfettoTrackEventExtra initialValue() { 45 return new PerfettoTrackEventExtra(); 46 } 47 }; 48 private static final AtomicLong sNamedTrackId = new AtomicLong(); 49 private static final Supplier<Flow> sFlowSupplier = Flow::new; 50 private static final Supplier<Builder> sBuilderSupplier = Builder::new; 51 private static final Supplier<FieldInt64> sFieldInt64Supplier = FieldInt64::new; 52 private static final Supplier<FieldDouble> sFieldDoubleSupplier = FieldDouble::new; 53 private static final Supplier<FieldString> sFieldStringSupplier = FieldString::new; 54 private static final Supplier<FieldNested> sFieldNestedSupplier = FieldNested::new; 55 56 private final List<PerfettoPointer> mPendingPointers = new ArrayList<>(); 57 private CounterInt64 mCounterInt64; 58 private CounterDouble mCounterDouble; 59 private Proto mProto; 60 private Flow mFlow; 61 private Flow mTerminatingFlow; 62 63 /** 64 * Represents a native pointer to a Perfetto C SDK struct. E.g. PerfettoTeHlExtra. 65 */ 66 public interface PerfettoPointer { 67 /** 68 * Returns the perfetto struct native pointer. 69 */ getPtr()70 long getPtr(); 71 } 72 73 /** 74 * Container for {@link Field} instances. 75 */ 76 public interface FieldContainer { 77 /** 78 * Add {@link Field} to the container. 79 */ addField(PerfettoPointer field)80 void addField(PerfettoPointer field); 81 } 82 83 /** 84 * RingBuffer implemented on top of a SparseArray. 85 * 86 * Bounds a SparseArray with a FIFO algorithm. 87 */ 88 private static final class RingBuffer<T> { 89 private final int mCapacity; 90 private final int[] mKeyArray; 91 private final T[] mValueArray; 92 private int mWriteEnd = 0; 93 RingBuffer(int capacity)94 RingBuffer(int capacity) { 95 mCapacity = capacity; 96 mKeyArray = new int[capacity]; 97 mValueArray = (T[]) new Object[capacity]; 98 } 99 put(int key, T value)100 public void put(int key, T value) { 101 mKeyArray[mWriteEnd] = key; 102 mValueArray[mWriteEnd] = value; 103 mWriteEnd = (mWriteEnd + 1) % mCapacity; 104 } 105 get(int key)106 public T get(int key) { 107 for (int i = 0; i < mCapacity; i++) { 108 if (mKeyArray[i] == key) { 109 return mValueArray[i]; 110 } 111 } 112 return null; 113 } 114 } 115 116 private static final class Pool<T> { 117 private final int mCapacity; 118 private final T[] mValueArray; 119 private int mIdx = 0; 120 Pool(int capacity)121 Pool(int capacity) { 122 mCapacity = capacity; 123 mValueArray = (T[]) new Object[capacity]; 124 } 125 reset()126 public void reset() { 127 mIdx = 0; 128 } 129 get(Supplier<T> supplier)130 public T get(Supplier<T> supplier) { 131 if (mIdx >= mCapacity) { 132 return supplier.get(); 133 } 134 if (mValueArray[mIdx] == null) { 135 mValueArray[mIdx] = supplier.get(); 136 } 137 return mValueArray[mIdx++]; 138 } 139 } 140 141 /** 142 * Builder for Perfetto track event extras. 143 */ 144 public static final class Builder { 145 // For performance reasons, we hold a reference to mExtra as a holder for 146 // perfetto pointers being added. This way, we avoid an additional list to hold 147 // the pointers in Java and we can pass them down directly to native code. 148 private final PerfettoTrackEventExtra mExtra; 149 150 private int mTraceType; 151 private PerfettoTrace.Category mCategory; 152 private String mEventName; 153 private boolean mIsBuilt; 154 155 private Builder mParent; 156 private FieldContainer mCurrentContainer; 157 158 private final boolean mIsCategoryEnabled; 159 private final CounterInt64 mCounterInt64; 160 private final CounterDouble mCounterDouble; 161 private final Proto mProto; 162 private final Flow mFlow; 163 private final Flow mTerminatingFlow; 164 165 private final RingBuffer<NamedTrack> mNamedTrackCache; 166 private final RingBuffer<CounterTrack> mCounterTrackCache; 167 private final RingBuffer<ArgInt64> mArgInt64Cache; 168 private final RingBuffer<ArgBool> mArgBoolCache; 169 private final RingBuffer<ArgDouble> mArgDoubleCache; 170 private final RingBuffer<ArgString> mArgStringCache; 171 172 private final Pool<FieldInt64> mFieldInt64Cache; 173 private final Pool<FieldDouble> mFieldDoubleCache; 174 private final Pool<FieldString> mFieldStringCache; 175 private final Pool<FieldNested> mFieldNestedCache; 176 private final Pool<Builder> mBuilderCache; 177 Builder()178 private Builder() { 179 this(sTrackEventExtra.get(), true); 180 } 181 Builder(PerfettoTrackEventExtra extra, boolean isCategoryEnabled)182 public Builder(PerfettoTrackEventExtra extra, boolean isCategoryEnabled) { 183 mIsCategoryEnabled = isCategoryEnabled; 184 mExtra = extra; 185 mNamedTrackCache = mExtra == null ? null : mExtra.mNamedTrackCache; 186 mCounterTrackCache = mExtra == null ? null : mExtra.mCounterTrackCache; 187 mArgInt64Cache = mExtra == null ? null : mExtra.mArgInt64Cache; 188 mArgDoubleCache = mExtra == null ? null : mExtra.mArgDoubleCache; 189 mArgBoolCache = mExtra == null ? null : mExtra.mArgBoolCache; 190 mArgStringCache = mExtra == null ? null : mExtra.mArgStringCache; 191 mFieldInt64Cache = mExtra == null ? null : mExtra.mFieldInt64Cache; 192 mFieldDoubleCache = mExtra == null ? null : mExtra.mFieldDoubleCache; 193 mFieldStringCache = mExtra == null ? null : mExtra.mFieldStringCache; 194 mFieldNestedCache = mExtra == null ? null : mExtra.mFieldNestedCache; 195 mBuilderCache = mExtra == null ? null : mExtra.mBuilderCache; 196 197 mCounterInt64 = mExtra == null ? null : mExtra.getCounterInt64(); 198 mCounterDouble = mExtra == null ? null : mExtra.getCounterDouble(); 199 mProto = mExtra == null ? null : mExtra.getProto(); 200 mFlow = mExtra == null ? null : mExtra.getFlow(); 201 mTerminatingFlow = mExtra == null ? null : mExtra.getTerminatingFlow(); 202 } 203 204 /** 205 * Emits the track event. 206 */ emit()207 public void emit() { 208 if (!mIsCategoryEnabled) { 209 return; 210 } 211 if (DEBUG) { 212 checkParent(); 213 } 214 215 mIsBuilt = true; 216 native_emit(mTraceType, mCategory.getPtr(), mEventName, mExtra.getPtr()); 217 } 218 219 /** 220 * Initialize the builder for a new trace event. 221 */ init(int traceType, PerfettoTrace.Category category)222 public Builder init(int traceType, PerfettoTrace.Category category) { 223 if (!mIsCategoryEnabled) { 224 return this; 225 } 226 227 mTraceType = traceType; 228 mCategory = category; 229 mEventName = ""; 230 mFieldInt64Cache.reset(); 231 mFieldDoubleCache.reset(); 232 mFieldStringCache.reset(); 233 mFieldNestedCache.reset(); 234 mBuilderCache.reset(); 235 236 mExtra.reset(); 237 // Reset after on init in case the thread created builders without calling emit 238 return initInternal(this, null); 239 } 240 241 /** 242 * Sets the event name for the track event. 243 */ setEventName(String eventName)244 public Builder setEventName(String eventName) { 245 mEventName = eventName; 246 return this; 247 } 248 249 /** 250 * Adds a debug arg with key {@code name} and value {@code val}. 251 */ addArg(String name, long val)252 public Builder addArg(String name, long val) { 253 if (!mIsCategoryEnabled) { 254 return this; 255 } 256 if (DEBUG) { 257 checkParent(); 258 } 259 ArgInt64 arg = mArgInt64Cache.get(name.hashCode()); 260 if (arg == null || !arg.getName().equals(name)) { 261 arg = new ArgInt64(name); 262 mArgInt64Cache.put(name.hashCode(), arg); 263 } 264 arg.setValue(val); 265 mExtra.addPerfettoPointer(arg); 266 return this; 267 } 268 269 /** 270 * Adds a debug arg with key {@code name} and value {@code val}. 271 */ addArg(String name, boolean val)272 public Builder addArg(String name, boolean val) { 273 if (!mIsCategoryEnabled) { 274 return this; 275 } 276 if (DEBUG) { 277 checkParent(); 278 } 279 ArgBool arg = mArgBoolCache.get(name.hashCode()); 280 if (arg == null || !arg.getName().equals(name)) { 281 arg = new ArgBool(name); 282 mArgBoolCache.put(name.hashCode(), arg); 283 } 284 arg.setValue(val); 285 mExtra.addPerfettoPointer(arg); 286 return this; 287 } 288 289 /** 290 * Adds a debug arg with key {@code name} and value {@code val}. 291 */ addArg(String name, double val)292 public Builder addArg(String name, double val) { 293 if (!mIsCategoryEnabled) { 294 return this; 295 } 296 if (DEBUG) { 297 checkParent(); 298 } 299 ArgDouble arg = mArgDoubleCache.get(name.hashCode()); 300 if (arg == null || !arg.getName().equals(name)) { 301 arg = new ArgDouble(name); 302 mArgDoubleCache.put(name.hashCode(), arg); 303 } 304 arg.setValue(val); 305 mExtra.addPerfettoPointer(arg); 306 return this; 307 } 308 309 /** 310 * Adds a debug arg with key {@code name} and value {@code val}. 311 */ addArg(String name, String val)312 public Builder addArg(String name, String val) { 313 if (!mIsCategoryEnabled) { 314 return this; 315 } 316 if (DEBUG) { 317 checkParent(); 318 } 319 ArgString arg = mArgStringCache.get(name.hashCode()); 320 if (arg == null || !arg.getName().equals(name)) { 321 arg = new ArgString(name); 322 mArgStringCache.put(name.hashCode(), arg); 323 } 324 arg.setValue(val); 325 mExtra.addPerfettoPointer(arg); 326 return this; 327 } 328 329 /** 330 * Adds a flow with {@code id}. 331 */ setFlow(long id)332 public Builder setFlow(long id) { 333 if (!mIsCategoryEnabled) { 334 return this; 335 } 336 if (DEBUG) { 337 checkParent(); 338 } 339 mFlow.setProcessFlow(id); 340 mExtra.addPerfettoPointer(mFlow); 341 return this; 342 } 343 344 /** 345 * Adds a terminating flow with {@code id}. 346 */ setTerminatingFlow(long id)347 public Builder setTerminatingFlow(long id) { 348 if (!mIsCategoryEnabled) { 349 return this; 350 } 351 if (DEBUG) { 352 checkParent(); 353 } 354 mTerminatingFlow.setProcessTerminatingFlow(id); 355 mExtra.addPerfettoPointer(mTerminatingFlow); 356 return this; 357 } 358 359 /** 360 * Adds the events to a named track instead of the thread track where the 361 * event occurred. 362 */ usingNamedTrack(long parentUuid, String name)363 public Builder usingNamedTrack(long parentUuid, String name) { 364 if (!mIsCategoryEnabled) { 365 return this; 366 } 367 if (DEBUG) { 368 checkParent(); 369 } 370 371 NamedTrack track = mNamedTrackCache.get(name.hashCode()); 372 if (track == null || !track.getName().equals(name)) { 373 track = new NamedTrack(name, parentUuid); 374 mNamedTrackCache.put(name.hashCode(), track); 375 } 376 mExtra.addPerfettoPointer(track); 377 return this; 378 } 379 380 /** 381 * Adds the events to a process scoped named track instead of the thread track where the 382 * event occurred. 383 */ usingProcessNamedTrack(String name)384 public Builder usingProcessNamedTrack(String name) { 385 if (!mIsCategoryEnabled) { 386 return this; 387 } 388 return usingNamedTrack(PerfettoTrace.getProcessTrackUuid(), name); 389 } 390 391 /** 392 * Adds the events to a thread scoped named track instead of the thread track where the 393 * event occurred. 394 */ usingThreadNamedTrack(long tid, String name)395 public Builder usingThreadNamedTrack(long tid, String name) { 396 if (!mIsCategoryEnabled) { 397 return this; 398 } 399 return usingNamedTrack(PerfettoTrace.getThreadTrackUuid(tid), name); 400 } 401 402 /** 403 * Adds the events to a counter track instead. This is required for 404 * setting counter values. 405 */ usingCounterTrack(long parentUuid, String name)406 public Builder usingCounterTrack(long parentUuid, String name) { 407 if (!mIsCategoryEnabled) { 408 return this; 409 } 410 if (DEBUG) { 411 checkParent(); 412 } 413 414 CounterTrack track = mCounterTrackCache.get(name.hashCode()); 415 if (track == null || !track.getName().equals(name)) { 416 track = new CounterTrack(name, parentUuid); 417 mCounterTrackCache.put(name.hashCode(), track); 418 } 419 mExtra.addPerfettoPointer(track); 420 return this; 421 } 422 423 /** 424 * Adds the events to a process scoped counter track instead. This is required for 425 * setting counter values. 426 */ usingProcessCounterTrack(String name)427 public Builder usingProcessCounterTrack(String name) { 428 if (!mIsCategoryEnabled) { 429 return this; 430 } 431 return usingCounterTrack(PerfettoTrace.getProcessTrackUuid(), name); 432 } 433 434 /** 435 * Adds the events to a thread scoped counter track instead. This is required for 436 * setting counter values. 437 */ usingThreadCounterTrack(long tid, String name)438 public Builder usingThreadCounterTrack(long tid, String name) { 439 if (!mIsCategoryEnabled) { 440 return this; 441 } 442 return usingCounterTrack(PerfettoTrace.getThreadTrackUuid(tid), name); 443 } 444 445 /** 446 * Sets a long counter value on the event. 447 * 448 */ setCounter(long val)449 public Builder setCounter(long val) { 450 if (!mIsCategoryEnabled) { 451 return this; 452 } 453 if (DEBUG) { 454 checkParent(); 455 } 456 mCounterInt64.setValue(val); 457 mExtra.addPerfettoPointer(mCounterInt64); 458 return this; 459 } 460 461 /** 462 * Sets a double counter value on the event. 463 * 464 */ setCounter(double val)465 public Builder setCounter(double val) { 466 if (!mIsCategoryEnabled) { 467 return this; 468 } 469 if (DEBUG) { 470 checkParent(); 471 } 472 mCounterDouble.setValue(val); 473 mExtra.addPerfettoPointer(mCounterDouble); 474 return this; 475 } 476 477 /** 478 * Adds a proto field with field id {@code id} and value {@code val}. 479 */ addField(long id, long val)480 public Builder addField(long id, long val) { 481 if (!mIsCategoryEnabled) { 482 return this; 483 } 484 if (DEBUG) { 485 checkContainer(); 486 } 487 FieldInt64 field = mFieldInt64Cache.get(sFieldInt64Supplier); 488 field.setValue(id, val); 489 mExtra.addPerfettoPointer(mCurrentContainer, field); 490 return this; 491 } 492 493 /** 494 * Adds a proto field with field id {@code id} and value {@code val}. 495 */ addField(long id, double val)496 public Builder addField(long id, double val) { 497 if (!mIsCategoryEnabled) { 498 return this; 499 } 500 if (DEBUG) { 501 checkContainer(); 502 } 503 FieldDouble field = mFieldDoubleCache.get(sFieldDoubleSupplier); 504 field.setValue(id, val); 505 mExtra.addPerfettoPointer(mCurrentContainer, field); 506 return this; 507 } 508 509 /** 510 * Adds a proto field with field id {@code id} and value {@code val}. 511 */ addField(long id, String val)512 public Builder addField(long id, String val) { 513 if (!mIsCategoryEnabled) { 514 return this; 515 } 516 if (DEBUG) { 517 checkContainer(); 518 } 519 FieldString field = mFieldStringCache.get(sFieldStringSupplier); 520 field.setValue(id, val); 521 mExtra.addPerfettoPointer(mCurrentContainer, field); 522 return this; 523 } 524 525 /** 526 * Begins a proto field. 527 * Fields can be added from this point and there must be a corresponding 528 * {@link endProto}. 529 * 530 * The proto field is a singleton and all proto fields get added inside the 531 * one {@link beginProto} and {@link endProto} within the {@link Builder}. 532 */ beginProto()533 public Builder beginProto() { 534 if (!mIsCategoryEnabled) { 535 return this; 536 } 537 if (DEBUG) { 538 checkParent(); 539 } 540 mProto.clearFields(); 541 mExtra.addPerfettoPointer(mProto); 542 return mBuilderCache.get(sBuilderSupplier).initInternal(this, mProto); 543 } 544 545 /** 546 * Ends a proto field. 547 */ endProto()548 public Builder endProto() { 549 if (!mIsCategoryEnabled) { 550 return this; 551 } 552 if (mParent == null || mCurrentContainer == null) { 553 throw new IllegalStateException("No proto to end"); 554 } 555 return mParent; 556 } 557 558 /** 559 * Begins a nested proto field with field id {@code id}. 560 * Fields can be added from this point and there must be a corresponding 561 * {@link endNested}. 562 */ beginNested(long id)563 public Builder beginNested(long id) { 564 if (!mIsCategoryEnabled) { 565 return this; 566 } 567 if (DEBUG) { 568 checkContainer(); 569 } 570 FieldNested field = mFieldNestedCache.get(sFieldNestedSupplier); 571 field.setId(id); 572 mExtra.addPerfettoPointer(mCurrentContainer, field); 573 return mBuilderCache.get(sBuilderSupplier).initInternal(this, field); 574 } 575 576 /** 577 * Ends a nested proto field. 578 */ endNested()579 public Builder endNested() { 580 if (!mIsCategoryEnabled) { 581 return this; 582 } 583 if (mParent == null || mCurrentContainer == null) { 584 throw new IllegalStateException("No nested field to end"); 585 } 586 return mParent; 587 } 588 589 initInternal(Builder parent, FieldContainer field)590 private Builder initInternal(Builder parent, FieldContainer field) { 591 mParent = parent; 592 mCurrentContainer = field; 593 mIsBuilt = false; 594 595 return this; 596 } 597 checkState()598 private void checkState() { 599 if (mIsBuilt) { 600 throw new IllegalStateException( 601 "This builder has already been used. Create a new builder for another event."); 602 } 603 } 604 checkParent()605 private void checkParent() { 606 checkState(); 607 if (!this.equals(mParent)) { 608 throw new IllegalStateException("Operation not supported for proto"); 609 } 610 } 611 checkContainer()612 private void checkContainer() { 613 checkState(); 614 if (mCurrentContainer == null) { 615 throw new IllegalStateException( 616 "Field operations must be within beginProto/endProto block"); 617 } 618 } 619 } 620 621 /** 622 * Start a {@link Builder} to build a {@link PerfettoTrackEventExtra}. 623 */ builder(boolean isCategoryEnabled)624 public static Builder builder(boolean isCategoryEnabled) { 625 if (isCategoryEnabled) { 626 return sTrackEventExtra.get().mBuilderCache.get(sBuilderSupplier) 627 .initInternal(null, null); 628 } 629 return NO_OP_BUILDER; 630 } 631 632 private final RingBuffer<NamedTrack> mNamedTrackCache = 633 new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE); 634 private final RingBuffer<CounterTrack> mCounterTrackCache = 635 new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE); 636 637 private final RingBuffer<ArgInt64> mArgInt64Cache = new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE); 638 private final RingBuffer<ArgBool> mArgBoolCache = new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE); 639 private final RingBuffer<ArgDouble> mArgDoubleCache = new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE); 640 private final RingBuffer<ArgString> mArgStringCache = new RingBuffer(DEFAULT_EXTRA_CACHE_SIZE); 641 642 private final Pool<FieldInt64> mFieldInt64Cache = new Pool(DEFAULT_EXTRA_CACHE_SIZE); 643 private final Pool<FieldDouble> mFieldDoubleCache = new Pool(DEFAULT_EXTRA_CACHE_SIZE); 644 private final Pool<FieldString> mFieldStringCache = new Pool(DEFAULT_EXTRA_CACHE_SIZE); 645 private final Pool<FieldNested> mFieldNestedCache = new Pool(DEFAULT_EXTRA_CACHE_SIZE); 646 private final Pool<Builder> mBuilderCache = new Pool(DEFAULT_EXTRA_CACHE_SIZE); 647 648 private static final NativeAllocationRegistry sRegistry = 649 NativeAllocationRegistry.createMalloced( 650 PerfettoTrackEventExtra.class.getClassLoader(), native_delete()); 651 652 private final long mPtr; 653 private static final String TAG = "PerfettoTrackEventExtra"; 654 PerfettoTrackEventExtra()655 private PerfettoTrackEventExtra() { 656 mPtr = native_init(); 657 if (!RavenwoodEnvironment.getInstance().isRunningOnRavenwood()) { 658 sRegistry.registerNativeAllocation(this, mPtr); 659 } 660 } 661 662 /** 663 * Returns the native pointer. 664 */ getPtr()665 public long getPtr() { 666 return mPtr; 667 } 668 669 /** 670 * Adds a pointer representing a track event parameter. 671 */ addPerfettoPointer(PerfettoPointer extra)672 public void addPerfettoPointer(PerfettoPointer extra) { 673 native_add_arg(mPtr, extra.getPtr()); 674 mPendingPointers.add(extra); 675 } 676 677 /** 678 * Adds a pointer representing a track event parameter to the {@code container}. 679 */ addPerfettoPointer(FieldContainer container, PerfettoPointer extra)680 public void addPerfettoPointer(FieldContainer container, PerfettoPointer extra) { 681 container.addField(extra); 682 mPendingPointers.add(extra); 683 } 684 685 /** 686 * Resets the track event extra. 687 */ 688 @android.ravenwood.annotation.RavenwoodReplace reset()689 public void reset() { 690 native_clear_args(mPtr); 691 mPendingPointers.clear(); 692 } 693 694 @android.ravenwood.annotation.RavenwoodReplace getCounterInt64()695 private CounterInt64 getCounterInt64() { 696 if (mCounterInt64 == null) { 697 mCounterInt64 = new CounterInt64(); 698 } 699 return mCounterInt64; 700 } 701 702 @android.ravenwood.annotation.RavenwoodReplace getCounterDouble()703 private CounterDouble getCounterDouble() { 704 if (mCounterDouble == null) { 705 mCounterDouble = new CounterDouble(); 706 } 707 return mCounterDouble; 708 } 709 710 @android.ravenwood.annotation.RavenwoodReplace getProto()711 private Proto getProto() { 712 if (mProto == null) { 713 mProto = new Proto(); 714 } 715 return mProto; 716 } 717 718 @android.ravenwood.annotation.RavenwoodReplace getFlow()719 private Flow getFlow() { 720 if (mFlow == null) { 721 mFlow = new Flow(); 722 } 723 return mFlow; 724 } 725 726 @android.ravenwood.annotation.RavenwoodReplace getTerminatingFlow()727 private Flow getTerminatingFlow() { 728 if (mTerminatingFlow == null) { 729 mTerminatingFlow = new Flow(); 730 } 731 return mTerminatingFlow; 732 } 733 734 private static final class Flow implements PerfettoPointer { 735 private static final NativeAllocationRegistry sRegistry = 736 NativeAllocationRegistry.createMalloced( 737 Flow.class.getClassLoader(), native_delete()); 738 739 private final long mPtr; 740 private final long mExtraPtr; 741 Flow()742 Flow() { 743 mPtr = native_init(); 744 mExtraPtr = native_get_extra_ptr(mPtr); 745 sRegistry.registerNativeAllocation(this, mPtr); 746 } 747 setProcessFlow(long type)748 public void setProcessFlow(long type) { 749 native_set_process_flow(mPtr, type); 750 } 751 setProcessTerminatingFlow(long id)752 public void setProcessTerminatingFlow(long id) { 753 native_set_process_terminating_flow(mPtr, id); 754 } 755 756 @Override getPtr()757 public long getPtr() { 758 return mExtraPtr; 759 } 760 761 @CriticalNative native_init()762 private static native long native_init(); 763 @CriticalNative native_delete()764 private static native long native_delete(); 765 @CriticalNative native_set_process_flow(long ptr, long type)766 private static native void native_set_process_flow(long ptr, long type); 767 @CriticalNative native_set_process_terminating_flow(long ptr, long id)768 private static native void native_set_process_terminating_flow(long ptr, long id); 769 @CriticalNative native_get_extra_ptr(long ptr)770 private static native long native_get_extra_ptr(long ptr); 771 } 772 773 private static class NamedTrack implements PerfettoPointer { 774 private static final NativeAllocationRegistry sRegistry = 775 NativeAllocationRegistry.createMalloced( 776 NamedTrack.class.getClassLoader(), native_delete()); 777 778 private final long mPtr; 779 private final long mExtraPtr; 780 private final String mName; 781 NamedTrack(String name, long parentUuid)782 NamedTrack(String name, long parentUuid) { 783 mPtr = native_init(sNamedTrackId.incrementAndGet(), name, parentUuid); 784 mExtraPtr = native_get_extra_ptr(mPtr); 785 mName = name; 786 sRegistry.registerNativeAllocation(this, mPtr); 787 } 788 789 @Override getPtr()790 public long getPtr() { 791 return mExtraPtr; 792 } 793 getName()794 public String getName() { 795 return mName; 796 } 797 798 @FastNative native_init(long id, String name, long parentUuid)799 private static native long native_init(long id, String name, long parentUuid); 800 @CriticalNative native_delete()801 private static native long native_delete(); 802 @CriticalNative native_get_extra_ptr(long ptr)803 private static native long native_get_extra_ptr(long ptr); 804 } 805 806 private static final class CounterTrack implements PerfettoPointer { 807 private static final NativeAllocationRegistry sRegistry = 808 NativeAllocationRegistry.createMalloced( 809 CounterTrack.class.getClassLoader(), native_delete()); 810 811 private final long mPtr; 812 private final long mExtraPtr; 813 private final String mName; 814 CounterTrack(String name, long parentUuid)815 CounterTrack(String name, long parentUuid) { 816 mPtr = native_init(name, parentUuid); 817 mExtraPtr = native_get_extra_ptr(mPtr); 818 mName = name; 819 sRegistry.registerNativeAllocation(this, mPtr); 820 } 821 822 @Override getPtr()823 public long getPtr() { 824 return mExtraPtr; 825 } 826 getName()827 public String getName() { 828 return mName; 829 } 830 831 @FastNative native_init(String name, long parentUuid)832 private static native long native_init(String name, long parentUuid); 833 @CriticalNative native_delete()834 private static native long native_delete(); 835 @CriticalNative native_get_extra_ptr(long ptr)836 private static native long native_get_extra_ptr(long ptr); 837 } 838 839 private static final class CounterInt64 implements PerfettoPointer { 840 private static final NativeAllocationRegistry sRegistry = 841 NativeAllocationRegistry.createMalloced( 842 CounterInt64.class.getClassLoader(), native_delete()); 843 844 private final long mPtr; 845 private final long mExtraPtr; 846 CounterInt64()847 CounterInt64() { 848 mPtr = native_init(); 849 mExtraPtr = native_get_extra_ptr(mPtr); 850 sRegistry.registerNativeAllocation(this, mPtr); 851 } 852 853 @Override getPtr()854 public long getPtr() { 855 return mExtraPtr; 856 } 857 setValue(long value)858 public void setValue(long value) { 859 native_set_value(mPtr, value); 860 } 861 862 @CriticalNative native_init()863 private static native long native_init(); 864 @CriticalNative native_delete()865 private static native long native_delete(); 866 @CriticalNative native_set_value(long ptr, long value)867 private static native void native_set_value(long ptr, long value); 868 @CriticalNative native_get_extra_ptr(long ptr)869 private static native long native_get_extra_ptr(long ptr); 870 } 871 872 private static final class CounterDouble implements PerfettoPointer { 873 private static final NativeAllocationRegistry sRegistry = 874 NativeAllocationRegistry.createMalloced( 875 CounterDouble.class.getClassLoader(), native_delete()); 876 877 private final long mPtr; 878 private final long mExtraPtr; 879 CounterDouble()880 CounterDouble() { 881 mPtr = native_init(); 882 mExtraPtr = native_get_extra_ptr(mPtr); 883 sRegistry.registerNativeAllocation(this, mPtr); 884 } 885 886 @Override getPtr()887 public long getPtr() { 888 return mExtraPtr; 889 } 890 setValue(double value)891 public void setValue(double value) { 892 native_set_value(mPtr, value); 893 } 894 895 @CriticalNative native_init()896 private static native long native_init(); 897 @CriticalNative native_delete()898 private static native long native_delete(); 899 @CriticalNative native_set_value(long ptr, double value)900 private static native void native_set_value(long ptr, double value); 901 @CriticalNative native_get_extra_ptr(long ptr)902 private static native long native_get_extra_ptr(long ptr); 903 } 904 905 private static final class ArgInt64 implements PerfettoPointer { 906 private static final NativeAllocationRegistry sRegistry = 907 NativeAllocationRegistry.createMalloced( 908 ArgInt64.class.getClassLoader(), native_delete()); 909 910 // Private pointer holding Perfetto object with metadata 911 private final long mPtr; 912 913 // Public pointer to Perfetto object itself 914 private final long mExtraPtr; 915 916 private final String mName; 917 ArgInt64(String name)918 ArgInt64(String name) { 919 mPtr = native_init(name); 920 mExtraPtr = native_get_extra_ptr(mPtr); 921 mName = name; 922 sRegistry.registerNativeAllocation(this, mPtr); 923 } 924 925 @Override getPtr()926 public long getPtr() { 927 return mExtraPtr; 928 } 929 getName()930 public String getName() { 931 return mName; 932 } 933 setValue(long val)934 public void setValue(long val) { 935 native_set_value(mPtr, val); 936 } 937 938 @FastNative native_init(String name)939 private static native long native_init(String name); 940 @CriticalNative native_delete()941 private static native long native_delete(); 942 @CriticalNative native_get_extra_ptr(long ptr)943 private static native long native_get_extra_ptr(long ptr); 944 @CriticalNative native_set_value(long ptr, long val)945 private static native void native_set_value(long ptr, long val); 946 } 947 948 private static final class ArgBool implements PerfettoPointer { 949 private static final NativeAllocationRegistry sRegistry = 950 NativeAllocationRegistry.createMalloced( 951 ArgBool.class.getClassLoader(), native_delete()); 952 953 // Private pointer holding Perfetto object with metadata 954 private final long mPtr; 955 956 // Public pointer to Perfetto object itself 957 private final long mExtraPtr; 958 959 private final String mName; 960 ArgBool(String name)961 ArgBool(String name) { 962 mPtr = native_init(name); 963 mExtraPtr = native_get_extra_ptr(mPtr); 964 mName = name; 965 sRegistry.registerNativeAllocation(this, mPtr); 966 } 967 968 @Override getPtr()969 public long getPtr() { 970 return mExtraPtr; 971 } 972 getName()973 public String getName() { 974 return mName; 975 } 976 setValue(boolean val)977 public void setValue(boolean val) { 978 native_set_value(mPtr, val); 979 } 980 981 @FastNative native_init(String name)982 private static native long native_init(String name); 983 @CriticalNative native_delete()984 private static native long native_delete(); 985 @CriticalNative native_get_extra_ptr(long ptr)986 private static native long native_get_extra_ptr(long ptr); 987 @CriticalNative native_set_value(long ptr, boolean val)988 private static native void native_set_value(long ptr, boolean val); 989 } 990 991 private static final class ArgDouble implements PerfettoPointer { 992 private static final NativeAllocationRegistry sRegistry = 993 NativeAllocationRegistry.createMalloced( 994 ArgDouble.class.getClassLoader(), native_delete()); 995 996 // Private pointer holding Perfetto object with metadata 997 private final long mPtr; 998 999 // Public pointer to Perfetto object itself 1000 private final long mExtraPtr; 1001 1002 private final String mName; 1003 ArgDouble(String name)1004 ArgDouble(String name) { 1005 mPtr = native_init(name); 1006 mExtraPtr = native_get_extra_ptr(mPtr); 1007 mName = name; 1008 sRegistry.registerNativeAllocation(this, mPtr); 1009 } 1010 1011 @Override getPtr()1012 public long getPtr() { 1013 return mExtraPtr; 1014 } 1015 getName()1016 public String getName() { 1017 return mName; 1018 } 1019 setValue(double val)1020 public void setValue(double val) { 1021 native_set_value(mPtr, val); 1022 } 1023 1024 @FastNative native_init(String name)1025 private static native long native_init(String name); 1026 @CriticalNative native_delete()1027 private static native long native_delete(); 1028 @CriticalNative native_get_extra_ptr(long ptr)1029 private static native long native_get_extra_ptr(long ptr); 1030 @CriticalNative native_set_value(long ptr, double val)1031 private static native void native_set_value(long ptr, double val); 1032 } 1033 1034 private static final class ArgString implements PerfettoPointer { 1035 private static final NativeAllocationRegistry sRegistry = 1036 NativeAllocationRegistry.createMalloced( 1037 ArgString.class.getClassLoader(), native_delete()); 1038 1039 // Private pointer holding Perfetto object with metadata 1040 private final long mPtr; 1041 1042 // Public pointer to Perfetto object itself 1043 private final long mExtraPtr; 1044 1045 private final String mName; 1046 ArgString(String name)1047 ArgString(String name) { 1048 mPtr = native_init(name); 1049 mExtraPtr = native_get_extra_ptr(mPtr); 1050 mName = name; 1051 sRegistry.registerNativeAllocation(this, mPtr); 1052 } 1053 1054 @Override getPtr()1055 public long getPtr() { 1056 return mExtraPtr; 1057 } 1058 getName()1059 public String getName() { 1060 return mName; 1061 } 1062 setValue(String val)1063 public void setValue(String val) { 1064 native_set_value(mPtr, val); 1065 } 1066 1067 @FastNative native_init(String name)1068 private static native long native_init(String name); 1069 @CriticalNative native_delete()1070 private static native long native_delete(); 1071 @CriticalNative native_get_extra_ptr(long ptr)1072 private static native long native_get_extra_ptr(long ptr); 1073 @FastNative native_set_value(long ptr, String val)1074 private static native void native_set_value(long ptr, String val); 1075 } 1076 1077 private static final class Proto implements PerfettoPointer, FieldContainer { 1078 private static final NativeAllocationRegistry sRegistry = 1079 NativeAllocationRegistry.createMalloced( 1080 Proto.class.getClassLoader(), native_delete()); 1081 1082 // Private pointer holding Perfetto object with metadata 1083 private final long mPtr; 1084 1085 // Public pointer to Perfetto object itself 1086 private final long mExtraPtr; 1087 Proto()1088 Proto() { 1089 mPtr = native_init(); 1090 mExtraPtr = native_get_extra_ptr(mPtr); 1091 sRegistry.registerNativeAllocation(this, mPtr); 1092 } 1093 1094 @Override getPtr()1095 public long getPtr() { 1096 return mExtraPtr; 1097 } 1098 1099 @Override addField(PerfettoPointer field)1100 public void addField(PerfettoPointer field) { 1101 native_add_field(mPtr, field.getPtr()); 1102 } 1103 clearFields()1104 public void clearFields() { 1105 native_clear_fields(mPtr); 1106 } 1107 1108 @CriticalNative native_init()1109 private static native long native_init(); 1110 @CriticalNative native_delete()1111 private static native long native_delete(); 1112 @CriticalNative native_get_extra_ptr(long ptr)1113 private static native long native_get_extra_ptr(long ptr); 1114 @CriticalNative native_add_field(long ptr, long extraPtr)1115 private static native void native_add_field(long ptr, long extraPtr); 1116 @CriticalNative native_clear_fields(long ptr)1117 private static native void native_clear_fields(long ptr); 1118 } 1119 1120 private static final class FieldInt64 implements PerfettoPointer { 1121 private static final NativeAllocationRegistry sRegistry = 1122 NativeAllocationRegistry.createMalloced( 1123 FieldInt64.class.getClassLoader(), native_delete()); 1124 1125 // Private pointer holding Perfetto object with metadata 1126 private final long mPtr; 1127 1128 // Public pointer to Perfetto object itself 1129 private final long mFieldPtr; 1130 FieldInt64()1131 FieldInt64() { 1132 mPtr = native_init(); 1133 mFieldPtr = native_get_extra_ptr(mPtr); 1134 sRegistry.registerNativeAllocation(this, mPtr); 1135 } 1136 1137 @Override getPtr()1138 public long getPtr() { 1139 return mFieldPtr; 1140 } 1141 setValue(long id, long val)1142 public void setValue(long id, long val) { 1143 native_set_value(mPtr, id, val); 1144 } 1145 1146 @CriticalNative native_init()1147 private static native long native_init(); 1148 @CriticalNative native_delete()1149 private static native long native_delete(); 1150 @CriticalNative native_get_extra_ptr(long ptr)1151 private static native long native_get_extra_ptr(long ptr); 1152 @CriticalNative native_set_value(long ptr, long id, long val)1153 private static native void native_set_value(long ptr, long id, long val); 1154 } 1155 1156 private static final class FieldDouble implements PerfettoPointer { 1157 private static final NativeAllocationRegistry sRegistry = 1158 NativeAllocationRegistry.createMalloced( 1159 FieldDouble.class.getClassLoader(), native_delete()); 1160 1161 // Private pointer holding Perfetto object with metadata 1162 private final long mPtr; 1163 1164 // Public pointer to Perfetto object itself 1165 private final long mFieldPtr; 1166 FieldDouble()1167 FieldDouble() { 1168 mPtr = native_init(); 1169 mFieldPtr = native_get_extra_ptr(mPtr); 1170 sRegistry.registerNativeAllocation(this, mPtr); 1171 } 1172 1173 @Override getPtr()1174 public long getPtr() { 1175 return mFieldPtr; 1176 } 1177 setValue(long id, double val)1178 public void setValue(long id, double val) { 1179 native_set_value(mPtr, id, val); 1180 } 1181 1182 @CriticalNative native_init()1183 private static native long native_init(); 1184 @CriticalNative native_delete()1185 private static native long native_delete(); 1186 @CriticalNative native_get_extra_ptr(long ptr)1187 private static native long native_get_extra_ptr(long ptr); 1188 @CriticalNative native_set_value(long ptr, long id, double val)1189 private static native void native_set_value(long ptr, long id, double val); 1190 } 1191 1192 private static final class FieldString implements PerfettoPointer { 1193 private static final NativeAllocationRegistry sRegistry = 1194 NativeAllocationRegistry.createMalloced( 1195 FieldString.class.getClassLoader(), native_delete()); 1196 1197 // Private pointer holding Perfetto object with metadata 1198 private final long mPtr; 1199 1200 // Public pointer to Perfetto object itself 1201 private final long mFieldPtr; 1202 FieldString()1203 FieldString() { 1204 mPtr = native_init(); 1205 mFieldPtr = native_get_extra_ptr(mPtr); 1206 sRegistry.registerNativeAllocation(this, mPtr); 1207 } 1208 1209 @Override getPtr()1210 public long getPtr() { 1211 return mFieldPtr; 1212 } 1213 setValue(long id, String val)1214 public void setValue(long id, String val) { 1215 native_set_value(mPtr, id, val); 1216 } 1217 1218 @CriticalNative native_init()1219 private static native long native_init(); 1220 @CriticalNative native_delete()1221 private static native long native_delete(); 1222 @CriticalNative native_get_extra_ptr(long ptr)1223 private static native long native_get_extra_ptr(long ptr); 1224 @FastNative native_set_value(long ptr, long id, String val)1225 private static native void native_set_value(long ptr, long id, String val); 1226 } 1227 1228 private static final class FieldNested implements PerfettoPointer, FieldContainer { 1229 private static final NativeAllocationRegistry sRegistry = 1230 NativeAllocationRegistry.createMalloced( 1231 FieldNested.class.getClassLoader(), native_delete()); 1232 1233 // Private pointer holding Perfetto object with metadata 1234 private final long mPtr; 1235 1236 // Public pointer to Perfetto object itself 1237 private final long mFieldPtr; 1238 FieldNested()1239 FieldNested() { 1240 mPtr = native_init(); 1241 mFieldPtr = native_get_extra_ptr(mPtr); 1242 sRegistry.registerNativeAllocation(this, mPtr); 1243 } 1244 1245 @Override getPtr()1246 public long getPtr() { 1247 return mFieldPtr; 1248 } 1249 1250 @Override addField(PerfettoPointer field)1251 public void addField(PerfettoPointer field) { 1252 native_add_field(mPtr, field.getPtr()); 1253 } 1254 setId(long id)1255 public void setId(long id) { 1256 native_set_id(mPtr, id); 1257 } 1258 1259 @CriticalNative native_init()1260 private static native long native_init(); 1261 @CriticalNative native_delete()1262 private static native long native_delete(); 1263 @CriticalNative native_get_extra_ptr(long ptr)1264 private static native long native_get_extra_ptr(long ptr); 1265 @CriticalNative native_add_field(long ptr, long extraPtr)1266 private static native void native_add_field(long ptr, long extraPtr); 1267 @CriticalNative native_set_id(long ptr, long id)1268 private static native void native_set_id(long ptr, long id); 1269 } 1270 1271 @CriticalNative 1272 @android.ravenwood.annotation.RavenwoodReplace native_init()1273 private static native long native_init(); 1274 @CriticalNative 1275 @android.ravenwood.annotation.RavenwoodReplace native_delete()1276 private static native long native_delete(); 1277 @CriticalNative native_add_arg(long ptr, long extraPtr)1278 private static native void native_add_arg(long ptr, long extraPtr); 1279 @CriticalNative native_clear_args(long ptr)1280 private static native void native_clear_args(long ptr); 1281 @FastNative native_emit(int type, long tag, String name, long ptr)1282 private static native void native_emit(int type, long tag, String name, long ptr); 1283 native_init$ravenwood()1284 private static long native_init$ravenwood() { 1285 // Tracing currently completely disabled under Ravenwood 1286 return 0; 1287 } 1288 native_delete$ravenwood()1289 private static long native_delete$ravenwood() { 1290 // Tracing currently completely disabled under Ravenwood 1291 return 0; 1292 } 1293 getCounterInt64$ravenwood()1294 private CounterInt64 getCounterInt64$ravenwood() { 1295 // Tracing currently completely disabled under Ravenwood 1296 return null; 1297 } 1298 getCounterDouble$ravenwood()1299 private CounterDouble getCounterDouble$ravenwood() { 1300 // Tracing currently completely disabled under Ravenwood 1301 return null; 1302 } 1303 getProto$ravenwood()1304 private Proto getProto$ravenwood() { 1305 // Tracing currently completely disabled under Ravenwood 1306 return null; 1307 } 1308 getFlow$ravenwood()1309 private Flow getFlow$ravenwood() { 1310 // Tracing currently completely disabled under Ravenwood 1311 return null; 1312 } 1313 getTerminatingFlow$ravenwood()1314 private Flow getTerminatingFlow$ravenwood() { 1315 // Tracing currently completely disabled under Ravenwood 1316 return null; 1317 } 1318 reset$ravenwood()1319 private void reset$ravenwood() { 1320 // Tracing currently completely disabled under Ravenwood 1321 } 1322 } 1323