• 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 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