1 /*
2 * Copyright 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 #define FRAMEWORK_CATEGORIES(C) \
18 C(always, "always", "Always category") \
19 C(graphics, "graphics", "Graphics category") \
20 C(input, "input", "Input category") \
21 C(view, "view", "View category") \
22 C(webview, "webview", "WebView category") \
23 C(windowmanager, "wm", "WindowManager category") \
24 C(activitymanager, "am", "ActivityManager category") \
25 C(syncmanager, "syncmanager", "SyncManager category") \
26 C(audio, "audio", "Audio category") \
27 C(video, "video", "Video category") \
28 C(camera, "camera", "Camera category") \
29 C(hal, "hal", "HAL category") \
30 C(app, "app", "App category") \
31 C(resources, "res", "Resources category") \
32 C(dalvik, "dalvik", "Dalvik category") \
33 C(rs, "rs", "RS category") \
34 C(bionic, "bionic", "Bionic category") \
35 C(power, "power", "Power category") \
36 C(packagemanager, "packagemanager", "PackageManager category") \
37 C(systemserver, "ss", "System Server category") \
38 C(database, "database", "Database category") \
39 C(network, "network", "Network category") \
40 C(adb, "adb", "ADB category") \
41 C(vibrator, "vibrator", "Vibrator category") \
42 C(aidl, "aidl", "AIDL category") \
43 C(nnapi, "nnapi", "NNAPI category") \
44 C(rro, "rro", "RRO category") \
45 C(thermal, "thermal", "Thermal category")
46
47 #include "tracing_perfetto_internal.h"
48
49 #include <inttypes.h>
50
51 #include <mutex>
52
53 #include <android_os.h>
54
55 #include "perfetto/public/compiler.h"
56 #include "perfetto/public/producer.h"
57 #include "perfetto/public/te_category_macros.h"
58 #include "perfetto/public/te_macros.h"
59 #include "perfetto/public/track_event.h"
60 #include "trace_categories.h"
61 #include "trace_result.h"
62
63 namespace tracing_perfetto {
64
65 namespace internal {
66
67 namespace {
68
69 PERFETTO_TE_CATEGORIES_DECLARE(FRAMEWORK_CATEGORIES);
70
71 PERFETTO_TE_CATEGORIES_DEFINE(FRAMEWORK_CATEGORIES);
72
73 std::atomic_bool is_perfetto_registered = false;
74
toCategory(uint64_t inCategory)75 struct PerfettoTeCategory* toCategory(uint64_t inCategory) {
76 switch (inCategory) {
77 case TRACE_CATEGORY_ALWAYS:
78 return &always;
79 case TRACE_CATEGORY_GRAPHICS:
80 return &graphics;
81 case TRACE_CATEGORY_INPUT:
82 return &input;
83 case TRACE_CATEGORY_VIEW:
84 return &view;
85 case TRACE_CATEGORY_WEBVIEW:
86 return &webview;
87 case TRACE_CATEGORY_WINDOW_MANAGER:
88 return &windowmanager;
89 case TRACE_CATEGORY_ACTIVITY_MANAGER:
90 return &activitymanager;
91 case TRACE_CATEGORY_SYNC_MANAGER:
92 return &syncmanager;
93 case TRACE_CATEGORY_AUDIO:
94 return &audio;
95 case TRACE_CATEGORY_VIDEO:
96 return &video;
97 case TRACE_CATEGORY_CAMERA:
98 return &camera;
99 case TRACE_CATEGORY_HAL:
100 return &hal;
101 case TRACE_CATEGORY_APP:
102 return &app;
103 case TRACE_CATEGORY_RESOURCES:
104 return &resources;
105 case TRACE_CATEGORY_DALVIK:
106 return &dalvik;
107 case TRACE_CATEGORY_RS:
108 return &rs;
109 case TRACE_CATEGORY_BIONIC:
110 return &bionic;
111 case TRACE_CATEGORY_POWER:
112 return &power;
113 case TRACE_CATEGORY_PACKAGE_MANAGER:
114 return &packagemanager;
115 case TRACE_CATEGORY_SYSTEM_SERVER:
116 return &systemserver;
117 case TRACE_CATEGORY_DATABASE:
118 return &database;
119 case TRACE_CATEGORY_NETWORK:
120 return &network;
121 case TRACE_CATEGORY_ADB:
122 return &adb;
123 case TRACE_CATEGORY_VIBRATOR:
124 return &vibrator;
125 case TRACE_CATEGORY_AIDL:
126 return &aidl;
127 case TRACE_CATEGORY_NNAPI:
128 return &nnapi;
129 case TRACE_CATEGORY_RRO:
130 return &rro;
131 case TRACE_CATEGORY_THERMAL:
132 return &thermal;
133 default:
134 return nullptr;
135 }
136 }
137
138 } // namespace
139
isPerfettoRegistered()140 bool isPerfettoRegistered() {
141 return is_perfetto_registered;
142 }
143
toPerfettoCategory(uint64_t category)144 struct PerfettoTeCategory* toPerfettoCategory(uint64_t category) {
145 struct PerfettoTeCategory* perfettoCategory = toCategory(category);
146 if (perfettoCategory == nullptr) {
147 return nullptr;
148 }
149
150 bool enabled = PERFETTO_UNLIKELY(PERFETTO_ATOMIC_LOAD_EXPLICIT(
151 (*perfettoCategory).enabled, PERFETTO_MEMORY_ORDER_RELAXED));
152 return enabled ? perfettoCategory : nullptr;
153 }
154
registerWithPerfetto(bool test)155 void registerWithPerfetto(bool test) {
156 if (!android::os::perfetto_sdk_tracing()) {
157 return;
158 }
159
160 static std::once_flag registration;
161 std::call_once(registration, [test]() {
162 struct PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
163 args.backends = test ? PERFETTO_BACKEND_IN_PROCESS : PERFETTO_BACKEND_SYSTEM;
164 PerfettoProducerInit(args);
165 PerfettoTeInit();
166 PERFETTO_TE_REGISTER_CATEGORIES(FRAMEWORK_CATEGORIES);
167 is_perfetto_registered = true;
168 });
169 }
170
perfettoTraceBegin(const struct PerfettoTeCategory & category,const char * name)171 Result perfettoTraceBegin(const struct PerfettoTeCategory& category, const char* name) {
172 PERFETTO_TE(category, PERFETTO_TE_SLICE_BEGIN(name));
173 return Result::SUCCESS;
174 }
175
perfettoTraceEnd(const struct PerfettoTeCategory & category)176 Result perfettoTraceEnd(const struct PerfettoTeCategory& category) {
177 PERFETTO_TE(category, PERFETTO_TE_SLICE_END());
178 return Result::SUCCESS;
179 }
180
perfettoTraceAsyncBeginForTrack(const struct PerfettoTeCategory & category,const char * name,const char * trackName,uint64_t cookie)181 Result perfettoTraceAsyncBeginForTrack(const struct PerfettoTeCategory& category, const char* name,
182 const char* trackName, uint64_t cookie) {
183 PERFETTO_TE(
184 category, PERFETTO_TE_SLICE_BEGIN(name),
185 PERFETTO_TE_NAMED_TRACK(trackName, cookie, PerfettoTeProcessTrackUuid()));
186 return Result::SUCCESS;
187 }
188
perfettoTraceAsyncEndForTrack(const struct PerfettoTeCategory & category,const char * trackName,uint64_t cookie)189 Result perfettoTraceAsyncEndForTrack(const struct PerfettoTeCategory& category,
190 const char* trackName, uint64_t cookie) {
191 PERFETTO_TE(
192 category, PERFETTO_TE_SLICE_END(),
193 PERFETTO_TE_NAMED_TRACK(trackName, cookie, PerfettoTeProcessTrackUuid()));
194 return Result::SUCCESS;
195 }
196
perfettoTraceAsyncBegin(const struct PerfettoTeCategory & category,const char * name,uint64_t cookie)197 Result perfettoTraceAsyncBegin(const struct PerfettoTeCategory& category, const char* name,
198 uint64_t cookie) {
199 return perfettoTraceAsyncBeginForTrack(category, name, name, cookie);
200 }
201
perfettoTraceAsyncEnd(const struct PerfettoTeCategory & category,const char * name,uint64_t cookie)202 Result perfettoTraceAsyncEnd(const struct PerfettoTeCategory& category, const char* name,
203 uint64_t cookie) {
204 return perfettoTraceAsyncEndForTrack(category, name, cookie);
205 }
206
perfettoTraceInstant(const struct PerfettoTeCategory & category,const char * name)207 Result perfettoTraceInstant(const struct PerfettoTeCategory& category, const char* name) {
208 PERFETTO_TE(category, PERFETTO_TE_INSTANT(name));
209 return Result::SUCCESS;
210 }
211
perfettoTraceInstantForTrack(const struct PerfettoTeCategory & category,const char * trackName,const char * name)212 Result perfettoTraceInstantForTrack(const struct PerfettoTeCategory& category,
213 const char* trackName, const char* name) {
214 PERFETTO_TE(
215 category, PERFETTO_TE_INSTANT(name),
216 PERFETTO_TE_NAMED_TRACK(trackName, 1, PerfettoTeProcessTrackUuid()));
217 return Result::SUCCESS;
218 }
219
perfettoTraceCounter(const struct PerfettoTeCategory & category,const char * name,int64_t value)220 Result perfettoTraceCounter(const struct PerfettoTeCategory& category,
221 [[maybe_unused]] const char* name, int64_t value) {
222 PERFETTO_TE(category, PERFETTO_TE_COUNTER(),
223 PERFETTO_TE_INT_COUNTER(value));
224 return Result::SUCCESS;
225 }
226
getDefaultCategories()227 uint64_t getDefaultCategories() {
228 return TRACE_CATEGORIES;
229 }
230
231 } // namespace internal
232
233 } // namespace tracing_perfetto
234