xref: /aosp_15_r20/external/cronet/base/android/trace_event_binding.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <jni.h>
6 
7 #include <set>
8 
9 #include "base/android/jni_string.h"
10 #include "base/android/trace_event_binding.h"
11 #include "base/metrics/histogram_macros.h"
12 #include "base/trace_event/base_tracing.h"
13 #include "base/tracing_buildflags.h"
14 #include "build/robolectric_buildflags.h"
15 
16 #if BUILDFLAG(IS_ROBOLECTRIC)
17 #include "base/base_robolectric_jni/TraceEvent_jni.h"  // nogncheck
18 #else
19 #include "base/base_jni/TraceEvent_jni.h"
20 #endif
21 
22 #if BUILDFLAG(ENABLE_BASE_TRACING)
23 #include "base/trace_event/trace_event_impl.h"  // no-presubmit-check
24 #include "third_party/perfetto/include/perfetto/tracing/track.h"  // no-presubmit-check nogncheck
25 #include "third_party/perfetto/protos/perfetto/config/chrome/chrome_config.gen.h"  // nogncheck
26 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
27 
28 namespace base {
29 namespace android {
30 
31 #if BUILDFLAG(ENABLE_BASE_TRACING)
32 
33 namespace {
34 
35 constexpr const char kAndroidViewHierarchyTraceCategory[] =
36     TRACE_DISABLED_BY_DEFAULT("android_view_hierarchy");
37 constexpr const char kAndroidViewHierarchyEventName[] = "AndroidView";
38 
39 #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
40 class TraceEnabledObserver : public perfetto::TrackEventSessionObserver {
41  public:
GetInstance()42   static TraceEnabledObserver* GetInstance() {
43     static base::NoDestructor<TraceEnabledObserver> instance;
44     return instance.get();
45   }
46 
47   // perfetto::TrackEventSessionObserver implementation
OnSetup(const perfetto::DataSourceBase::SetupArgs & args)48   void OnSetup(const perfetto::DataSourceBase::SetupArgs& args) override {
49     trace_event::TraceConfig trace_config(
50         args.config->chrome_config().trace_config());
51     event_name_filtering_per_session_[args.internal_instance_index] =
52         trace_config.IsEventPackageNameFilterEnabled();
53   }
54 
OnStart(const perfetto::DataSourceBase::StartArgs &)55   void OnStart(const perfetto::DataSourceBase::StartArgs&) override {
56     JNIEnv* env = jni_zero::AttachCurrentThread();
57     base::android::Java_TraceEvent_setEnabled(env, true);
58     base::android::Java_TraceEvent_setEventNameFilteringEnabled(
59         env, EventNameFilteringEnabled());
60   }
61 
OnStop(const perfetto::DataSourceBase::StopArgs & args)62   void OnStop(const perfetto::DataSourceBase::StopArgs& args) override {
63     event_name_filtering_per_session_.erase(args.internal_instance_index);
64 
65     JNIEnv* env = jni_zero::AttachCurrentThread();
66     base::android::Java_TraceEvent_setEnabled(
67         env, !event_name_filtering_per_session_.empty());
68     base::android::Java_TraceEvent_setEventNameFilteringEnabled(
69         env, EventNameFilteringEnabled());
70   }
71 
72  private:
73   friend class base::NoDestructor<TraceEnabledObserver>;
74   TraceEnabledObserver() = default;
75   ~TraceEnabledObserver() override = default;
76 
77   // Return true if event name filtering is requested by at least one tracing
78   // session.
EventNameFilteringEnabled() const79   bool EventNameFilteringEnabled() const {
80     bool event_name_filtering_enabled = false;
81     for (const auto& entry : event_name_filtering_per_session_) {
82       if (entry.second) {
83         event_name_filtering_enabled = true;
84       }
85     }
86     return event_name_filtering_enabled;
87   }
88 
89   std::unordered_map<uint32_t, bool> event_name_filtering_per_session_;
90 };
91 
92 #else   // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
93 
94 class TraceEnabledObserver
95     : public trace_event::TraceLog::EnabledStateObserver {
96  public:
97   ~TraceEnabledObserver() override = default;
98 
99   // trace_event::TraceLog::EnabledStateObserver:
OnTraceLogEnabled()100   void OnTraceLogEnabled() override {
101     JNIEnv* env = jni_zero::AttachCurrentThread();
102     base::android::Java_TraceEvent_setEnabled(env, true);
103     if (base::trace_event::TraceLog::GetInstance()
104             ->GetCurrentTraceConfig()
105             .IsEventPackageNameFilterEnabled()) {
106       base::android::Java_TraceEvent_setEventNameFilteringEnabled(env, true);
107     }
108   }
109 
OnTraceLogDisabled()110   void OnTraceLogDisabled() override {
111     JNIEnv* env = jni_zero::AttachCurrentThread();
112     base::android::Java_TraceEvent_setEnabled(env, false);
113     base::android::Java_TraceEvent_setEventNameFilteringEnabled(env, false);
114   }
115 };
116 #endif  // !BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
117 
118 }  // namespace
119 
JNI_TraceEvent_RegisterEnabledObserver(JNIEnv * env)120 static void JNI_TraceEvent_RegisterEnabledObserver(JNIEnv* env) {
121 #if BUILDFLAG(USE_PERFETTO_CLIENT_LIBRARY)
122   base::android::Java_TraceEvent_setEnabled(env, base::TrackEvent::IsEnabled());
123   base::TrackEvent::AddSessionObserver(TraceEnabledObserver::GetInstance());
124 #else
125   bool enabled = trace_event::TraceLog::GetInstance()->IsEnabled();
126   base::android::Java_TraceEvent_setEnabled(env, enabled);
127   trace_event::TraceLog::GetInstance()->AddOwnedEnabledStateObserver(
128       std::make_unique<TraceEnabledObserver>());
129 #endif
130 }
131 
JNI_TraceEvent_ViewHierarchyDumpEnabled(JNIEnv * env)132 static jboolean JNI_TraceEvent_ViewHierarchyDumpEnabled(JNIEnv* env) {
133   static const unsigned char* enabled =
134       TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
135           kAndroidViewHierarchyTraceCategory);
136   return *enabled;
137 }
138 
JNI_TraceEvent_InitViewHierarchyDump(JNIEnv * env,jlong id,const JavaParamRef<jobject> & obj)139 static void JNI_TraceEvent_InitViewHierarchyDump(
140     JNIEnv* env,
141     jlong id,
142     const JavaParamRef<jobject>& obj) {
143   TRACE_EVENT(
144       kAndroidViewHierarchyTraceCategory, kAndroidViewHierarchyEventName,
145       perfetto::TerminatingFlow::ProcessScoped(static_cast<uint64_t>(id)),
146       [&](perfetto::EventContext ctx) {
147         auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
148         auto* dump = event->set_android_view_dump();
149         Java_TraceEvent_dumpViewHierarchy(env, reinterpret_cast<jlong>(dump),
150                                           obj);
151       });
152 }
153 
JNI_TraceEvent_StartActivityDump(JNIEnv * env,const JavaParamRef<jstring> & name,jlong dump_proto_ptr)154 static jlong JNI_TraceEvent_StartActivityDump(JNIEnv* env,
155                                               const JavaParamRef<jstring>& name,
156                                               jlong dump_proto_ptr) {
157   auto* dump = reinterpret_cast<perfetto::protos::pbzero::AndroidViewDump*>(
158       dump_proto_ptr);
159   auto* activity = dump->add_activity();
160   activity->set_name(ConvertJavaStringToUTF8(env, name));
161   return reinterpret_cast<jlong>(activity);
162 }
163 
JNI_TraceEvent_AddViewDump(JNIEnv * env,jint id,jint parent_id,jboolean is_shown,jboolean is_dirty,const JavaParamRef<jstring> & class_name,const JavaParamRef<jstring> & resource_name,jlong activity_proto_ptr)164 static void JNI_TraceEvent_AddViewDump(
165     JNIEnv* env,
166     jint id,
167     jint parent_id,
168     jboolean is_shown,
169     jboolean is_dirty,
170     const JavaParamRef<jstring>& class_name,
171     const JavaParamRef<jstring>& resource_name,
172     jlong activity_proto_ptr) {
173   auto* activity = reinterpret_cast<perfetto::protos::pbzero::AndroidActivity*>(
174       activity_proto_ptr);
175   auto* view = activity->add_view();
176   view->set_id(id);
177   view->set_parent_id(parent_id);
178   view->set_is_shown(is_shown);
179   view->set_is_dirty(is_dirty);
180   view->set_class_name(ConvertJavaStringToUTF8(env, class_name));
181   view->set_resource_name(ConvertJavaStringToUTF8(env, resource_name));
182 }
183 
184 #else  // BUILDFLAG(ENABLE_BASE_TRACING)
185 
186 // Empty implementations when TraceLog isn't available.
187 static void JNI_TraceEvent_RegisterEnabledObserver(JNIEnv* env) {
188   base::android::Java_TraceEvent_setEnabled(env, false);
189   // This code should not be reached when base tracing is disabled. Calling
190   // setEventNameFilteringEnabled to avoid "unused function" warning.
191   base::android::Java_TraceEvent_setEventNameFilteringEnabled(env, false);
192 }
193 static jboolean JNI_TraceEvent_ViewHierarchyDumpEnabled(JNIEnv* env) {
194   return false;
195 }
196 static void JNI_TraceEvent_InitViewHierarchyDump(
197     JNIEnv* env,
198     jlong id,
199     const JavaParamRef<jobject>& obj) {
200   DCHECK(false);
201   // This code should not be reached when base tracing is disabled. Calling
202   // dumpViewHierarchy to avoid "unused function" warning.
203   Java_TraceEvent_dumpViewHierarchy(env, 0, obj);
204 }
205 static jlong JNI_TraceEvent_StartActivityDump(JNIEnv* env,
206                                               const JavaParamRef<jstring>& name,
207                                               jlong dump_proto_ptr) {
208   return 0;
209 }
210 static void JNI_TraceEvent_AddViewDump(
211     JNIEnv* env,
212     jint id,
213     jint parent_id,
214     jboolean is_shown,
215     jboolean is_dirty,
216     const JavaParamRef<jstring>& class_name,
217     const JavaParamRef<jstring>& resource_name,
218     jlong activity_proto_ptr) {}
219 
220 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
221 
222 namespace {
223 
224 // Boilerplate for safely converting Java data to TRACE_EVENT data.
225 class TraceEventDataConverter {
226  public:
TraceEventDataConverter(JNIEnv * env,jstring jarg)227   TraceEventDataConverter(JNIEnv* env, jstring jarg)
228       : has_arg_(jarg != nullptr),
229         arg_(jarg ? ConvertJavaStringToUTF8(env, jarg) : "") {}
230 
231   TraceEventDataConverter(const TraceEventDataConverter&) = delete;
232   TraceEventDataConverter& operator=(const TraceEventDataConverter&) = delete;
233 
234   ~TraceEventDataConverter() = default;
235 
236   // Return saved values to pass to TRACE_EVENT macros.
arg_name()237   const char* arg_name() { return has_arg_ ? "arg" : nullptr; }
arg()238   const std::string& arg() { return arg_; }
239 
240  private:
241   bool has_arg_;
242   std::string arg_;
243 };
244 
245 }  // namespace
246 
JNI_TraceEvent_Instant(JNIEnv * env,const JavaParamRef<jstring> & jname,const JavaParamRef<jstring> & jarg)247 static void JNI_TraceEvent_Instant(JNIEnv* env,
248                                    const JavaParamRef<jstring>& jname,
249                                    const JavaParamRef<jstring>& jarg) {
250   TraceEventDataConverter converter(env, jarg);
251 
252   if (converter.arg_name()) {
253     TRACE_EVENT_INSTANT(
254         internal::kJavaTraceCategory, nullptr, converter.arg_name(),
255         converter.arg(), [&](::perfetto::EventContext& ctx) {
256           ctx.event()->set_name(ConvertJavaStringToUTF8(env, jname));
257         });
258   } else {
259     TRACE_EVENT_INSTANT(
260         internal::kJavaTraceCategory, nullptr,
261         [&](::perfetto::EventContext& ctx) {
262           ctx.event()->set_name(ConvertJavaStringToUTF8(env, jname));
263         });
264   }
265 }
266 
JNI_TraceEvent_InstantAndroidIPC(JNIEnv * env,const JavaParamRef<jstring> & jname,jlong jdur)267 static void JNI_TraceEvent_InstantAndroidIPC(JNIEnv* env,
268                                              const JavaParamRef<jstring>& jname,
269                                              jlong jdur) {
270   TRACE_EVENT_INSTANT(
271       internal::kJavaTraceCategory, "AndroidIPC",
272       [&](perfetto::EventContext ctx) {
273         auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
274         auto* android_ipc = event->set_android_ipc();
275         android_ipc->set_name(ConvertJavaStringToUTF8(env, jname));
276         android_ipc->set_dur_ms(jdur);
277       });
278 }
279 
280 #if BUILDFLAG(ENABLE_BASE_TRACING)
281 
JNI_TraceEvent_InstantAndroidToolbar(JNIEnv * env,jint block_reason,jint allow_reason,jint snapshot_diff)282 static void JNI_TraceEvent_InstantAndroidToolbar(JNIEnv* env,
283                                                  jint block_reason,
284                                                  jint allow_reason,
285                                                  jint snapshot_diff) {
286   using AndroidToolbar = perfetto::protos::pbzero::AndroidToolbar;
287   TRACE_EVENT_INSTANT(
288       internal::kJavaTraceCategory, "AndroidToolbar",
289       [&](perfetto::EventContext ctx) {
290         auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
291         auto* android_toolbar = event->set_android_toolbar();
292         if (block_reason >= 0) {
293           android_toolbar->set_block_capture_reason(
294               static_cast<AndroidToolbar::BlockCaptureReason>(block_reason));
295         }
296         if (allow_reason >= 0) {
297           android_toolbar->set_allow_capture_reason(
298               static_cast<AndroidToolbar::AllowCaptureReason>(allow_reason));
299         }
300         if (snapshot_diff >= 0) {
301           android_toolbar->set_snapshot_difference(
302               static_cast<AndroidToolbar::SnapshotDifference>(snapshot_diff));
303         }
304       });
305 }
306 
307 #else  // BUILDFLAG(ENABLE_BASE_TRACING)
308 
309 // Empty implementations when TraceLog isn't available.
JNI_TraceEvent_InstantAndroidToolbar(JNIEnv * env,jint block_reason,jint allow_reason,jint snapshot_diff)310 static void JNI_TraceEvent_InstantAndroidToolbar(JNIEnv* env,
311                                                  jint block_reason,
312                                                  jint allow_reason,
313                                                  jint snapshot_diff) {}
314 
315 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
316 
JNI_TraceEvent_WebViewStartupTotalFactoryInit(JNIEnv * env,jlong start_time_ms,jlong duration_ms)317 static void JNI_TraceEvent_WebViewStartupTotalFactoryInit(JNIEnv* env,
318                                                           jlong start_time_ms,
319                                                           jlong duration_ms) {
320 #if BUILDFLAG(ENABLE_BASE_TRACING)
321   auto t = perfetto::Track::ThreadScoped(env);
322   auto desc = t.Serialize();
323   desc.set_name("android_webview.timeline");
324   TRACE_EVENT_BEGIN("android_webview.timeline",
325                     "WebView.Startup.CreationTime.TotalFactoryInitTime", t,
326                     TimeTicks() + Milliseconds(start_time_ms));
327   TRACE_EVENT_END("android_webview.timeline", t,
328                   TimeTicks() + Milliseconds(start_time_ms + duration_ms));
329 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
330 }
331 
JNI_TraceEvent_WebViewStartupStage1(JNIEnv * env,jlong start_time_ms,jlong duration_ms)332 static void JNI_TraceEvent_WebViewStartupStage1(JNIEnv* env,
333                                                 jlong start_time_ms,
334                                                 jlong duration_ms) {
335 #if BUILDFLAG(ENABLE_BASE_TRACING)
336   auto t = perfetto::Track::ThreadScoped(env);
337   auto desc = t.Serialize();
338   desc.set_name("android_webview.timeline");
339   TRACE_EVENT_BEGIN("android_webview.timeline",
340                     "WebView.Startup.CreationTime.Stage1.FactoryInit", t,
341                     TimeTicks() + Milliseconds(start_time_ms));
342   TRACE_EVENT_END("android_webview.timeline", t,
343                   TimeTicks() + Milliseconds(start_time_ms + duration_ms));
344 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
345 }
346 
JNI_TraceEvent_WebViewStartupStage2(JNIEnv * env,jlong start_time_ms,jlong duration_ms,jboolean is_cold_startup)347 static void JNI_TraceEvent_WebViewStartupStage2(JNIEnv* env,
348                                                 jlong start_time_ms,
349                                                 jlong duration_ms,
350                                                 jboolean is_cold_startup) {
351 #if BUILDFLAG(ENABLE_BASE_TRACING)
352   auto t = perfetto::Track::ThreadScoped(env);
353   auto desc = t.Serialize();
354   desc.set_name("android_webview.timeline");
355   if (is_cold_startup) {
356     TRACE_EVENT_BEGIN("android_webview.timeline",
357                       "WebView.Startup.CreationTime.Stage2.ProviderInit.Cold",
358                       t, TimeTicks() + Milliseconds(start_time_ms));
359   } else {
360     TRACE_EVENT_BEGIN("android_webview.timeline",
361                       "WebView.Startup.CreationTime.Stage2.ProviderInit.Warm",
362                       t, TimeTicks() + Milliseconds(start_time_ms));
363   }
364 
365   TRACE_EVENT_END("android_webview.timeline", t,
366                   TimeTicks() + Milliseconds(start_time_ms + duration_ms));
367 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
368 }
369 
JNI_TraceEvent_WebViewStartupStartChromiumLocked(JNIEnv * env,jlong start_time_ms,jlong duration_ms)370 static void JNI_TraceEvent_WebViewStartupStartChromiumLocked(
371     JNIEnv* env,
372     jlong start_time_ms,
373     jlong duration_ms) {
374 #if BUILDFLAG(ENABLE_BASE_TRACING)
375   auto t = perfetto::Track::ThreadScoped(env);
376   auto desc = t.Serialize();
377   desc.set_name("android_webview.timeline");
378   TrackEvent::SetTrackDescriptor(t, desc);
379   TRACE_EVENT_BEGIN("android_webview.timeline",
380                     "WebView.Startup.CreationTime.StartChromiumLocked", t,
381                     TimeTicks() + Milliseconds(start_time_ms));
382   TRACE_EVENT_END("android_webview.timeline", t,
383                   TimeTicks() + Milliseconds(start_time_ms + duration_ms));
384 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
385 }
386 
JNI_TraceEvent_StartupActivityStart(JNIEnv * env,jlong activity_id,jlong start_time_ms)387 static void JNI_TraceEvent_StartupActivityStart(JNIEnv* env,
388                                                 jlong activity_id,
389                                                 jlong start_time_ms) {
390   TRACE_EVENT_INSTANT(
391       "interactions", "Startup.ActivityStart",
392       TimeTicks() + Milliseconds(start_time_ms),
393       [&](perfetto::EventContext ctx) {
394         auto* start_up = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>()
395                              ->set_startup();
396         start_up->set_activity_id(activity_id);
397       });
398 }
399 
JNI_TraceEvent_StartupLaunchCause(JNIEnv * env,jlong activity_id,jlong start_time_ms,jint cause)400 static void JNI_TraceEvent_StartupLaunchCause(JNIEnv* env,
401                                               jlong activity_id,
402                                               jlong start_time_ms,
403                                               jint cause) {
404 #if BUILDFLAG(ENABLE_BASE_TRACING)
405   using Startup = perfetto::protos::pbzero::StartUp;
406   auto launchType = Startup::OTHER;
407   switch (cause) {
408     case Startup::CUSTOM_TAB:
409       launchType = Startup::CUSTOM_TAB;
410       break;
411     case Startup::TWA:
412       launchType = Startup::TWA;
413       break;
414     case Startup::RECENTS:
415       launchType = Startup::RECENTS;
416       break;
417     case Startup::RECENTS_OR_BACK:
418       launchType = Startup::RECENTS_OR_BACK;
419       break;
420     case Startup::FOREGROUND_WHEN_LOCKED:
421       launchType = Startup::FOREGROUND_WHEN_LOCKED;
422       break;
423     case Startup::MAIN_LAUNCHER_ICON:
424       launchType = Startup::MAIN_LAUNCHER_ICON;
425       break;
426     case Startup::MAIN_LAUNCHER_ICON_SHORTCUT:
427       launchType = Startup::MAIN_LAUNCHER_ICON_SHORTCUT;
428       break;
429     case Startup::HOME_SCREEN_WIDGET:
430       launchType = Startup::HOME_SCREEN_WIDGET;
431       break;
432     case Startup::OPEN_IN_BROWSER_FROM_MENU:
433       launchType = Startup::OPEN_IN_BROWSER_FROM_MENU;
434       break;
435     case Startup::EXTERNAL_SEARCH_ACTION_INTENT:
436       launchType = Startup::EXTERNAL_SEARCH_ACTION_INTENT;
437       break;
438     case Startup::NOTIFICATION:
439       launchType = Startup::NOTIFICATION;
440       break;
441     case Startup::EXTERNAL_VIEW_INTENT:
442       launchType = Startup::EXTERNAL_VIEW_INTENT;
443       break;
444     case Startup::OTHER_CHROME:
445       launchType = Startup::OTHER_CHROME;
446       break;
447     case Startup::WEBAPK_CHROME_DISTRIBUTOR:
448       launchType = Startup::WEBAPK_CHROME_DISTRIBUTOR;
449       break;
450     case Startup::WEBAPK_OTHER_DISTRIBUTOR:
451       launchType = Startup::WEBAPK_OTHER_DISTRIBUTOR;
452       break;
453     case Startup::HOME_SCREEN_SHORTCUT:
454       launchType = Startup::HOME_SCREEN_SHORTCUT;
455       break;
456     case Startup::SHARE_INTENT:
457       launchType = Startup::SHARE_INTENT;
458       break;
459     case Startup::NFC:
460       launchType = Startup::NFC;
461       break;
462     default:
463       break;
464   }
465 
466   TRACE_EVENT_INSTANT(
467       "interactions,startup", "Startup.LaunchCause",
468       TimeTicks() + Milliseconds(start_time_ms),
469       [&](perfetto::EventContext ctx) {
470         auto* start_up = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>()
471                              ->set_startup();
472         start_up->set_activity_id(activity_id);
473         start_up->set_launch_cause(launchType);
474       });
475 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
476 }
477 
JNI_TraceEvent_StartupTimeToFirstVisibleContent2(JNIEnv * env,jlong activity_id,jlong start_time_ms,jlong duration_ms)478 static void JNI_TraceEvent_StartupTimeToFirstVisibleContent2(
479     JNIEnv* env,
480     jlong activity_id,
481     jlong start_time_ms,
482     jlong duration_ms) {
483 #if BUILDFLAG(ENABLE_BASE_TRACING)
484   [[maybe_unused]] const perfetto::Track track(
485       base::trace_event::GetNextGlobalTraceId(),
486       perfetto::ProcessTrack::Current());
487   TRACE_EVENT_BEGIN(
488       "interactions,startup", "Startup.TimeToFirstVisibleContent2", track,
489       TimeTicks() + Milliseconds(start_time_ms),
490       [&](perfetto::EventContext ctx) {
491         auto* start_up = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>()
492                              ->set_startup();
493         start_up->set_activity_id(activity_id);
494       });
495 
496   TRACE_EVENT_END("interactions,startup", track,
497                   TimeTicks() + Milliseconds(start_time_ms + duration_ms));
498 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
499 }
500 
JNI_TraceEvent_Begin(JNIEnv * env,const JavaParamRef<jstring> & jname,const JavaParamRef<jstring> & jarg)501 static void JNI_TraceEvent_Begin(JNIEnv* env,
502                                  const JavaParamRef<jstring>& jname,
503                                  const JavaParamRef<jstring>& jarg) {
504   TraceEventDataConverter converter(env, jarg);
505   if (converter.arg_name()) {
506     TRACE_EVENT_BEGIN(
507         internal::kJavaTraceCategory, nullptr, converter.arg_name(),
508         converter.arg(), [&](::perfetto::EventContext& ctx) {
509           ctx.event()->set_name(ConvertJavaStringToUTF8(env, jname));
510         });
511   } else {
512     TRACE_EVENT_BEGIN(
513         internal::kJavaTraceCategory, nullptr,
514         [&](::perfetto::EventContext& ctx) {
515           ctx.event()->set_name(ConvertJavaStringToUTF8(env, jname));
516         });
517   }
518 }
519 
JNI_TraceEvent_BeginWithIntArg(JNIEnv * env,const JavaParamRef<jstring> & jname,jint jarg)520 static void JNI_TraceEvent_BeginWithIntArg(JNIEnv* env,
521                                            const JavaParamRef<jstring>& jname,
522                                            jint jarg) {
523   TRACE_EVENT_BEGIN(
524       internal::kJavaTraceCategory, nullptr, "arg", jarg,
525       [&](::perfetto::EventContext& ctx) {
526         ctx.event()->set_name(ConvertJavaStringToUTF8(env, jname));
527       });
528 }
529 
JNI_TraceEvent_End(JNIEnv * env,const JavaParamRef<jstring> & jarg,jlong jflow)530 static void JNI_TraceEvent_End(JNIEnv* env,
531                                const JavaParamRef<jstring>& jarg,
532                                jlong jflow) {
533   TraceEventDataConverter converter(env, jarg);
534   bool has_arg = converter.arg_name();
535   bool has_flow = jflow != 0;
536   if (has_arg && has_flow) {
537     TRACE_EVENT_END(internal::kJavaTraceCategory,
538                     perfetto::Flow::ProcessScoped(static_cast<uint64_t>(jflow)),
539                     converter.arg_name(), converter.arg());
540   } else if (has_arg) {
541     TRACE_EVENT_END(internal::kJavaTraceCategory, converter.arg_name(),
542                     converter.arg());
543   } else if (has_flow) {
544     TRACE_EVENT_END(
545         internal::kJavaTraceCategory,
546         perfetto::Flow::ProcessScoped(static_cast<uint64_t>(jflow)));
547   } else {
548     TRACE_EVENT_END(internal::kJavaTraceCategory);
549   }
550 }
551 
JNI_TraceEvent_BeginToplevel(JNIEnv * env,const JavaParamRef<jstring> & jtarget)552 static void JNI_TraceEvent_BeginToplevel(JNIEnv* env,
553                                          const JavaParamRef<jstring>& jtarget) {
554   TRACE_EVENT_BEGIN(
555       internal::kToplevelTraceCategory, nullptr,
556       [&](::perfetto::EventContext& ctx) {
557         ctx.event()->set_name(ConvertJavaStringToUTF8(env, jtarget));
558       });
559 }
560 
JNI_TraceEvent_EndToplevel(JNIEnv * env)561 static void JNI_TraceEvent_EndToplevel(JNIEnv* env) {
562   TRACE_EVENT_END(internal::kToplevelTraceCategory);
563 }
564 
JNI_TraceEvent_StartAsync(JNIEnv * env,const JavaParamRef<jstring> & jname,jlong jid)565 static void JNI_TraceEvent_StartAsync(JNIEnv* env,
566                                       const JavaParamRef<jstring>& jname,
567                                       jlong jid) {
568   TRACE_EVENT_BEGIN(
569       internal::kJavaTraceCategory, nullptr,
570       perfetto::Track(static_cast<uint64_t>(jid)),
571       [&](::perfetto::EventContext& ctx) {
572         ctx.event()->set_name(ConvertJavaStringToUTF8(env, jname));
573       });
574 }
575 
JNI_TraceEvent_FinishAsync(JNIEnv * env,jlong jid)576 static void JNI_TraceEvent_FinishAsync(JNIEnv* env,
577                                        jlong jid) {
578   TRACE_EVENT_END(internal::kJavaTraceCategory,
579                   perfetto::Track(static_cast<uint64_t>(jid)));
580 }
581 
582 }  // namespace android
583 }  // namespace base
584