trace_event_binding.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <jni.h>
  5. #include <set>
  6. #include "base/android/jni_string.h"
  7. #include "base/android/trace_event_binding.h"
  8. #include "base/base_jni_headers/TraceEvent_jni.h"
  9. #include "base/metrics/histogram_macros.h"
  10. #include "base/trace_event/base_tracing.h"
  11. #include "base/tracing_buildflags.h"
  12. #if BUILDFLAG(ENABLE_BASE_TRACING)
  13. #include "base/trace_event/trace_event_impl.h" // no-presubmit-check
  14. #endif // BUILDFLAG(ENABLE_BASE_TRACING)
  15. namespace base {
  16. namespace android {
  17. #if BUILDFLAG(ENABLE_BASE_TRACING)
  18. namespace {
  19. constexpr const char kAndroidViewHierarchyTraceCategory[] =
  20. TRACE_DISABLED_BY_DEFAULT("android_view_hierarchy");
  21. constexpr const char kAndroidViewHierarchyEventName[] = "AndroidView";
  22. class TraceEnabledObserver
  23. : public trace_event::TraceLog::EnabledStateObserver {
  24. public:
  25. ~TraceEnabledObserver() override = default;
  26. // trace_event::TraceLog::EnabledStateObserver:
  27. void OnTraceLogEnabled() override {
  28. JNIEnv* env = base::android::AttachCurrentThread();
  29. base::android::Java_TraceEvent_setEnabled(env, true);
  30. if (base::trace_event::TraceLog::GetInstance()
  31. ->GetCurrentTraceConfig()
  32. .IsEventPackageNameFilterEnabled()) {
  33. base::android::Java_TraceEvent_setEventNameFilteringEnabled(env, true);
  34. }
  35. }
  36. void OnTraceLogDisabled() override {
  37. JNIEnv* env = base::android::AttachCurrentThread();
  38. base::android::Java_TraceEvent_setEnabled(env, false);
  39. base::android::Java_TraceEvent_setEventNameFilteringEnabled(env, false);
  40. }
  41. };
  42. } // namespace
  43. static void JNI_TraceEvent_RegisterEnabledObserver(JNIEnv* env) {
  44. bool enabled = trace_event::TraceLog::GetInstance()->IsEnabled();
  45. base::android::Java_TraceEvent_setEnabled(env, enabled);
  46. trace_event::TraceLog::GetInstance()->AddOwnedEnabledStateObserver(
  47. std::make_unique<TraceEnabledObserver>());
  48. }
  49. static void JNI_TraceEvent_StartATrace(
  50. JNIEnv* env,
  51. const JavaParamRef<jstring>& category_filter) {
  52. std::string category_filter_utf8 =
  53. ConvertJavaStringToUTF8(env, category_filter);
  54. base::trace_event::TraceLog::GetInstance()->StartATrace(category_filter_utf8);
  55. }
  56. static void JNI_TraceEvent_StopATrace(JNIEnv* env) {
  57. base::trace_event::TraceLog::GetInstance()->StopATrace();
  58. }
  59. static void JNI_TraceEvent_SetupATraceStartupTrace(
  60. JNIEnv* env,
  61. const JavaParamRef<jstring>& category_filter) {
  62. std::string category_filter_utf8 =
  63. ConvertJavaStringToUTF8(env, category_filter);
  64. base::trace_event::TraceLog::GetInstance()->SetupATraceStartupTrace(
  65. category_filter_utf8);
  66. }
  67. static jboolean JNI_TraceEvent_ViewHierarchyDumpEnabled(JNIEnv* env) {
  68. static const unsigned char* enabled =
  69. TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
  70. kAndroidViewHierarchyTraceCategory);
  71. return *enabled;
  72. }
  73. static void JNI_TraceEvent_InitViewHierarchyDump(JNIEnv* env) {
  74. SCOPED_UMA_HISTOGRAM_TIMER("Tracing.ViewHierarchyDump.DumpDuration");
  75. TRACE_EVENT_INSTANT(
  76. kAndroidViewHierarchyTraceCategory, kAndroidViewHierarchyEventName,
  77. perfetto::Track::Global(0), [&](perfetto::EventContext ctx) {
  78. auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
  79. auto* dump = event->set_android_view_dump();
  80. Java_TraceEvent_dumpViewHierarchy(env, reinterpret_cast<jlong>(dump));
  81. });
  82. }
  83. static jlong JNI_TraceEvent_StartActivityDump(JNIEnv* env,
  84. const JavaParamRef<jstring>& name,
  85. jlong dump_proto_ptr) {
  86. auto* dump = reinterpret_cast<perfetto::protos::pbzero::AndroidViewDump*>(
  87. dump_proto_ptr);
  88. auto* activity = dump->add_activity();
  89. activity->set_name(ConvertJavaStringToUTF8(env, name));
  90. return reinterpret_cast<jlong>(activity);
  91. }
  92. static void JNI_TraceEvent_AddViewDump(
  93. JNIEnv* env,
  94. jint id,
  95. jint parent_id,
  96. jboolean is_shown,
  97. jboolean is_dirty,
  98. const JavaParamRef<jstring>& class_name,
  99. const JavaParamRef<jstring>& resource_name,
  100. jlong activity_proto_ptr) {
  101. auto* activity = reinterpret_cast<perfetto::protos::pbzero::AndroidActivity*>(
  102. activity_proto_ptr);
  103. auto* view = activity->add_view();
  104. view->set_id(id);
  105. view->set_parent_id(parent_id);
  106. view->set_is_shown(is_shown);
  107. view->set_is_dirty(is_dirty);
  108. view->set_class_name(ConvertJavaStringToUTF8(env, class_name));
  109. view->set_resource_name(ConvertJavaStringToUTF8(env, resource_name));
  110. }
  111. #else // BUILDFLAG(ENABLE_BASE_TRACING)
  112. // Empty implementations when TraceLog isn't available.
  113. static void JNI_TraceEvent_RegisterEnabledObserver(JNIEnv* env) {
  114. base::android::Java_TraceEvent_setEnabled(env, false);
  115. // This code should not be reached when base tracing is disabled. Calling
  116. // setEventNameFilteringEnabled to avoid "unused function" warning.
  117. base::android::Java_TraceEvent_setEventNameFilteringEnabled(env, false);
  118. }
  119. static void JNI_TraceEvent_StartATrace(JNIEnv* env,
  120. const JavaParamRef<jstring>&) {}
  121. static void JNI_TraceEvent_StopATrace(JNIEnv* env) {}
  122. static void JNI_TraceEvent_SetupATraceStartupTrace(
  123. JNIEnv* env,
  124. const JavaParamRef<jstring>&) {}
  125. static jboolean JNI_TraceEvent_ViewHierarchyDumpEnabled(JNIEnv* env) {
  126. return false;
  127. }
  128. static void JNI_TraceEvent_InitViewHierarchyDump(JNIEnv* env) {
  129. DCHECK(false);
  130. // This code should not be reached when base tracing is disabled. Calling
  131. // dumpViewHierarchy to avoid "unused function" warning.
  132. Java_TraceEvent_dumpViewHierarchy(env, 0);
  133. }
  134. static jlong JNI_TraceEvent_StartActivityDump(JNIEnv* env,
  135. const JavaParamRef<jstring>& name,
  136. jlong dump_proto_ptr) {
  137. return 0;
  138. }
  139. static void JNI_TraceEvent_AddViewDump(
  140. JNIEnv* env,
  141. jint id,
  142. jint parent_id,
  143. jboolean is_shown,
  144. jboolean is_dirty,
  145. const JavaParamRef<jstring>& class_name,
  146. const JavaParamRef<jstring>& resource_name,
  147. jlong activity_proto_ptr) {}
  148. #endif // BUILDFLAG(ENABLE_BASE_TRACING)
  149. namespace {
  150. // Boilerplate for safely converting Java data to TRACE_EVENT data.
  151. class TraceEventDataConverter {
  152. public:
  153. TraceEventDataConverter(JNIEnv* env, jstring jname, jstring jarg)
  154. : name_(ConvertJavaStringToUTF8(env, jname)),
  155. has_arg_(jarg != nullptr),
  156. arg_(jarg ? ConvertJavaStringToUTF8(env, jarg) : "") {}
  157. TraceEventDataConverter(const TraceEventDataConverter&) = delete;
  158. TraceEventDataConverter& operator=(const TraceEventDataConverter&) = delete;
  159. ~TraceEventDataConverter() = default;
  160. // Return saved values to pass to TRACE_EVENT macros.
  161. const char* name() { return name_.c_str(); }
  162. const char* arg_name() { return has_arg_ ? "arg" : nullptr; }
  163. const std::string& arg() { return arg_; }
  164. private:
  165. std::string name_;
  166. bool has_arg_;
  167. std::string arg_;
  168. };
  169. } // namespace
  170. static void JNI_TraceEvent_Instant(JNIEnv* env,
  171. const JavaParamRef<jstring>& jname,
  172. const JavaParamRef<jstring>& jarg) {
  173. TraceEventDataConverter converter(env, jname, jarg);
  174. if (converter.arg_name()) {
  175. TRACE_EVENT_INSTANT(internal::kJavaTraceCategory, nullptr,
  176. converter.arg_name(), converter.arg(),
  177. [&](::perfetto::EventContext& ctx) {
  178. ctx.event()->set_name(converter.name());
  179. });
  180. } else {
  181. TRACE_EVENT_INSTANT(internal::kJavaTraceCategory, nullptr,
  182. [&](::perfetto::EventContext& ctx) {
  183. ctx.event()->set_name(converter.name());
  184. });
  185. }
  186. }
  187. static void JNI_TraceEvent_InstantAndroidIPC(JNIEnv* env,
  188. const JavaParamRef<jstring>& jname,
  189. jlong jdur) {
  190. TRACE_EVENT_INSTANT(
  191. internal::kJavaTraceCategory, "AndroidIPC",
  192. [&](perfetto::EventContext ctx) {
  193. TraceEventDataConverter converter(env, jname, nullptr);
  194. auto* event = ctx.event<perfetto::protos::pbzero::ChromeTrackEvent>();
  195. auto* android_ipc = event->set_android_ipc();
  196. android_ipc->set_name(converter.name());
  197. android_ipc->set_dur_ms(jdur);
  198. });
  199. }
  200. static void JNI_TraceEvent_Begin(JNIEnv* env,
  201. const JavaParamRef<jstring>& jname,
  202. const JavaParamRef<jstring>& jarg) {
  203. TraceEventDataConverter converter(env, jname, jarg);
  204. if (converter.arg_name()) {
  205. TRACE_EVENT_BEGIN(internal::kJavaTraceCategory, nullptr,
  206. converter.arg_name(), converter.arg(),
  207. [&](::perfetto::EventContext& ctx) {
  208. ctx.event()->set_name(converter.name());
  209. });
  210. } else {
  211. TRACE_EVENT_BEGIN(internal::kJavaTraceCategory, nullptr,
  212. [&](::perfetto::EventContext& ctx) {
  213. ctx.event()->set_name(converter.name());
  214. });
  215. }
  216. }
  217. static void JNI_TraceEvent_End(JNIEnv* env,
  218. const JavaParamRef<jstring>& jname,
  219. const JavaParamRef<jstring>& jarg) {
  220. TraceEventDataConverter converter(env, jname, jarg);
  221. if (converter.arg_name()) {
  222. TRACE_EVENT_END(internal::kJavaTraceCategory, converter.arg_name(),
  223. converter.arg());
  224. } else {
  225. TRACE_EVENT_END(internal::kJavaTraceCategory);
  226. }
  227. }
  228. static void JNI_TraceEvent_BeginToplevel(JNIEnv* env,
  229. const JavaParamRef<jstring>& jtarget) {
  230. std::string target = ConvertJavaStringToUTF8(env, jtarget);
  231. TRACE_EVENT_BEGIN(internal::kToplevelTraceCategory, nullptr,
  232. [&](::perfetto::EventContext& ctx) {
  233. ctx.event()->set_name(target.c_str());
  234. });
  235. }
  236. static void JNI_TraceEvent_EndToplevel(JNIEnv* env,
  237. const JavaParamRef<jstring>& jtarget) {
  238. std::string target = ConvertJavaStringToUTF8(env, jtarget);
  239. TRACE_EVENT_END(internal::kToplevelTraceCategory);
  240. }
  241. static void JNI_TraceEvent_StartAsync(JNIEnv* env,
  242. const JavaParamRef<jstring>& jname,
  243. jlong jid) {
  244. TraceEventDataConverter converter(env, jname, nullptr);
  245. TRACE_EVENT_BEGIN(internal::kJavaTraceCategory, nullptr,
  246. perfetto::Track(static_cast<uint64_t>(jid)),
  247. [&](::perfetto::EventContext& ctx) {
  248. ctx.event()->set_name(converter.name());
  249. });
  250. }
  251. static void JNI_TraceEvent_FinishAsync(JNIEnv* env,
  252. const JavaParamRef<jstring>& jname,
  253. jlong jid) {
  254. TraceEventDataConverter converter(env, jname, nullptr);
  255. TRACE_EVENT_END(internal::kJavaTraceCategory,
  256. perfetto::Track(static_cast<uint64_t>(jid)));
  257. }
  258. } // namespace android
  259. } // namespace base