• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 com.android.adservices.service.profiling;
18 
19 import com.android.adservices.service.Flags;
20 import com.android.adservices.service.common.BinderFlagReader;
21 import com.android.adservices.shared.util.Trace;
22 import com.android.internal.annotations.VisibleForTesting;
23 
24 import java.util.Set;
25 import java.util.concurrent.atomic.AtomicInteger;
26 
27 /**
28  * An abstraction layer used to collect all traces following the same naming convention.
29  *
30  * @hide
31  */
32 public class RbATraceProvider {
33     private static RbATrace sTrace;
34     private static final Object sLock = new Object();
35 
36     @VisibleForTesting
getTrace(Flags flags)37     static RbATrace getTrace(Flags flags) {
38         if (sTrace != null) {
39             return sTrace;
40         }
41 
42         synchronized (sLock) {
43             if (sTrace == null) {
44                 if (BinderFlagReader.readFlag(flags::getEnableRbAtrace)) {
45                     sTrace = new RbATraceImpl(new Trace(), new AtomicInteger());
46                 } else {
47                     sTrace = new NoOpRbATrace();
48                 }
49             }
50 
51             return sTrace;
52         }
53     }
54 
55     /** Should only be used in tests. */
56     @VisibleForTesting
setTrace(RbATrace trace)57     public static void setTrace(RbATrace trace) {
58         sTrace = trace;
59     }
60 
61     /**
62      * Writes a trace message for the {@code metricName} to indicate that a given section of code
63      * has begun. The trace name will be concatenated from the {@code featureName} and the {@code
64      * metricName}.
65      *
66      * @param featureName Use the {@code FeatureNames} to specify the feature name.
67      * @param metricName The metric name to appear in the trace.
68      * @param flags for accessing feature flags
69      */
beginSection(String featureName, String metricName, Flags flags)70     public static void beginSection(String featureName, String metricName, Flags flags) {
71         getTrace(flags).beginSection(featureName, metricName);
72     }
73 
74     /**
75      * Writes a trace message for the {@code className} {@code methodName} to indicate that a given
76      * section of code has begun. The trace name will be concatenated from the {@code featureName},
77      * {@code className} and the {@code methodName}.
78      *
79      * @param featureName Use the {@code FeatureNames} to specify the feature name.
80      * @param className The class name to appear in the trace.
81      * @param methodName The method name to appear in the trace.
82      * @param flags for accessing feature flags
83      */
beginSection( String featureName, String className, String methodName, Flags flags)84     public static void beginSection(
85             String featureName, String className, String methodName, Flags flags) {
86         getTrace(flags).beginSection(featureName, className, methodName);
87     }
88 
89     /**
90      * Writes a trace message for the {@code metricName} to indicate that a given section of code
91      * has begun. The trace name will be concatenated from the {@code featureName} and the {@code
92      * metricName}. Must be followed by a call to {@code endAsyncSection} with the same {@code
93      * featureName}, {@code metricName} and provided {@code cookie}. Asynchronous events do not need
94      * to be nested.
95      *
96      * @param featureName Use the {@code FeatureNames} to specify the feature name.
97      * @param metricName The metric name to appear in the trace.
98      * @param flags for accessing feature flags
99      * @return unique cookie for identifying trace.
100      */
beginAsyncSection(String featureName, String metricName, Flags flags)101     public static int beginAsyncSection(String featureName, String metricName, Flags flags) {
102         return getTrace(flags).beginAsyncSection(featureName, metricName);
103     }
104 
105     /**
106      * Writes a trace message for the {@code className} {@code methodName} to indicate that a given
107      * section of code has begun. The trace name will be concatenated from the {@code featureName},
108      * {@code className} and {@code methodName}. Must be followed by a call to {@code
109      * endAsyncSection} with the same {@code featureName}, {@code className}, {@code methodName} and
110      * provided {@code cookie}. Asynchronous events do not need to be nested.
111      *
112      * @param className The class name to appear in the trace.
113      * @param methodName The method name to appear in the trace.
114      * @param flags for accessing feature flags
115      * @return unique cookie for identifying trace.
116      */
beginAsyncSection( String featureName, String className, String methodName, Flags flags)117     public static int beginAsyncSection(
118             String featureName, String className, String methodName, Flags flags) {
119         return getTrace(flags).beginAsyncSection(featureName, className, methodName);
120     }
121 
122     /**
123      * Writes a trace message to indicate that a given section of code has ended.
124      *
125      * @param flags for accessing feature flags
126      */
endSection(Flags flags)127     public static void endSection(Flags flags) {
128         getTrace(flags).endSection();
129     }
130 
131     /**
132      * Writes a trace message to indicate that a given section of code has ended. Must be called
133      * exactly once for each call to {@code beginAsyncSection(java.lang.String, java.lang.String)}
134      * using the same parameters and provided {@code cookie}.
135      *
136      * @param featureName Use the {@code FeatureNames} to specify the feature name.
137      * @param metricName The metric name to appear in the trace.
138      * @param cookie a unique cookie for identifying trace.
139      * @param flags for accessing feature flags
140      */
endAsyncSection( String featureName, String metricName, int cookie, Flags flags)141     public static void endAsyncSection(
142             String featureName, String metricName, int cookie, Flags flags) {
143         getTrace(flags).endAsyncSection(featureName, metricName, cookie);
144     }
145 
146     /**
147      * Writes a trace message to indicate that a given section of code has ended. Must be called
148      * exactly once for each call to {@code beginAsyncSection(java.lang.String, java.lang.String,
149      * java.lang.String)} using the same parameters and provided {@code cookie}.
150      *
151      * @param featureName Use the {@code FeatureNames} to specify the feature name.
152      * @param className The class name to appear in the trace.
153      * @param methodName The method name to appear in the trace.
154      * @param cookie a unique cookie for identifying trace.
155      * @param flags for accessing feature flags
156      */
endAsyncSection( String featureName, String className, String methodName, int cookie, Flags flags)157     public static void endAsyncSection(
158             String featureName, String className, String methodName, int cookie, Flags flags) {
159         getTrace(flags).endAsyncSection(featureName, className, methodName, cookie);
160     }
161 
162     /** Feature name to group metrics from the same project together. */
163     public static final class FeatureNames {
164         public static final String MEASUREMENT_API = "MeasurementApi";
165         public static final String TOPICS_API = "TopicsApi";
166         public static final String AD_ID_API = "AdIdApi";
167         public static final String CONSENT_MANAGER = "ConsentManager";
168 
169         private static final Set<String> VALID_FEATURE_NAMES =
170                 Set.of(MEASUREMENT_API, TOPICS_API, AD_ID_API, CONSENT_MANAGER);
171 
FeatureNames()172         private FeatureNames() {}
173 
isValidFeatureName(String featureName)174         static boolean isValidFeatureName(String featureName) {
175             return VALID_FEATURE_NAMES.contains(featureName);
176         }
177     }
178 }
179