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