15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/android/trace_event_binding.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <jni.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h"
120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/debug/trace_event_impl.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jni/TraceEvent_jni.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace base {
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace android {
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kJavaCategory[] = "Java";
22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst char kToplevelCategory[] = "toplevel";
23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst char kLooperDispatchMessage[] = "Looper.dispatchMessage";
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Boilerplate for safely converting Java data to TRACE_EVENT data.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TraceEventDataConverter {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceEventDataConverter(JNIEnv* env,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          jstring jname,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          jstring jarg)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : env_(env),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        jname_(jname),
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        jarg_(jarg),
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        name_(env->GetStringUTFChars(jname, NULL)),
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        arg_(jarg ? env->GetStringUTFChars(jarg, NULL) : NULL) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ~TraceEventDataConverter() {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    env_->ReleaseStringUTFChars(jname_, name_);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (jarg_)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      env_->ReleaseStringUTFChars(jarg_, arg_);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return saves values to pass to TRACE_EVENT macros.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* name() { return name_; }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* arg_name() { return arg_ ? "arg" : NULL; }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* arg() { return arg_; }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  JNIEnv* env_;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jstring jname_;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jstring jarg_;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* name_;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* arg_;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TraceEventDataConverter);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass TraceEnabledObserver : public debug::TraceLog::EnabledStateObserver {
590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  public:
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual void OnTraceLogEnabled() OVERRIDE {
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      JNIEnv* env = base::android::AttachCurrentThread();
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::android::Java_TraceEvent_setEnabled(env, true);
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual void OnTraceLogDisabled() OVERRIDE {
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      JNIEnv* env = base::android::AttachCurrentThread();
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::android::Java_TraceEvent_setEnabled(env, false);
670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::LazyInstance<TraceEnabledObserver>::Leaky g_trace_enabled_state_observer_;
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstatic void RegisterEnabledObserver(JNIEnv* env, jclass clazz) {
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool enabled = debug::TraceLog::GetInstance()->IsEnabled();
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::android::Java_TraceEvent_setEnabled(env, enabled);
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  debug::TraceLog::GetInstance()->AddEnabledStateObserver(
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      g_trace_enabled_state_observer_.Pointer());
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void StartATrace(JNIEnv* env, jclass clazz) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::debug::TraceLog::GetInstance()->StartATrace();
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void StopATrace(JNIEnv* env, jclass clazz) {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::debug::TraceLog::GetInstance()->StopATrace();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void Instant(JNIEnv* env, jclass clazz,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    jstring jname, jstring jarg) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceEventDataConverter converter(env, jname, jarg);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (converter.arg()) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT_COPY_INSTANT1(kJavaCategory, converter.name(),
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              TRACE_EVENT_SCOPE_THREAD,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              converter.arg_name(), converter.arg());
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT_COPY_INSTANT0(kJavaCategory, converter.name(),
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              TRACE_EVENT_SCOPE_THREAD);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void Begin(JNIEnv* env, jclass clazz,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  jstring jname, jstring jarg) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceEventDataConverter converter(env, jname, jarg);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (converter.arg()) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT_COPY_BEGIN1(kJavaCategory, converter.name(),
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       converter.arg_name(), converter.arg());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT_COPY_BEGIN0(kJavaCategory, converter.name());
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void End(JNIEnv* env, jclass clazz,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                jstring jname, jstring jarg) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TraceEventDataConverter converter(env, jname, jarg);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (converter.arg()) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT_COPY_END1(kJavaCategory, converter.name(),
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     converter.arg_name(), converter.arg());
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT_COPY_END0(kJavaCategory, converter.name());
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochstatic void BeginToplevel(JNIEnv* env, jclass clazz) {
125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  TRACE_EVENT_BEGIN0(kToplevelCategory, kLooperDispatchMessage);
126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochstatic void EndToplevel(JNIEnv* env, jclass clazz) {
129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  TRACE_EVENT_END0(kToplevelCategory, kLooperDispatchMessage);
130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void StartAsync(JNIEnv* env, jclass clazz,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       jstring jname, jlong jid, jstring jarg) {
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TraceEventDataConverter converter(env, jname, jarg);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (converter.arg()) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT_COPY_ASYNC_BEGIN1(kJavaCategory,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  converter.name(),
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  jid,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  converter.arg_name(),
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  converter.arg());
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT_COPY_ASYNC_BEGIN0(kJavaCategory,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  converter.name(),
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  jid);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void FinishAsync(JNIEnv* env, jclass clazz,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        jstring jname, jlong jid, jstring jarg) {
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  TraceEventDataConverter converter(env, jname, jarg);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (converter.arg()) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT_COPY_ASYNC_END1(kJavaCategory,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                converter.name(),
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                jid,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                converter.arg_name(),
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                converter.arg());
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT_COPY_ASYNC_END0(kJavaCategory,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                converter.name(),
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                jid);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RegisterTraceEvent(JNIEnv* env) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return RegisterNativesImpl(env);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace android
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace base
170