• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 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 #include <jni.h>
18 
19 #include <cutils/trace.h>
20 #include <log/log.h>
21 #include <nativehelper/JNIHelp.h>
22 
23 #include <array>
24 
25 namespace android {
26 
sanitizeString(char * str)27 inline static void sanitizeString(char* str) {
28     while (*str) {
29         char c = *str;
30         if (c == '\n' || c == '|') {
31             *str = ' ';
32         }
33         str++;
34     }
35 }
36 
37 template<typename F>
withString(JNIEnv * env,jstring jstr,F callback)38 inline static void withString(JNIEnv* env, jstring jstr, F callback) {
39     // We need to handle the worst case of 1 character -> 4 bytes
40     // So make a buffer of size 4097 and let it hold a string with a maximum length
41     // of 1024. The extra last byte for the null terminator.
42     std::array<char, 4097> buffer;
43     // We have no idea of knowing how much data GetStringUTFRegion wrote, so null it out in
44     // advance so we can have a reliable null terminator
45     memset(buffer.data(), 0, buffer.size());
46     jsize size = std::min(env->GetStringLength(jstr), 1024);
47     env->GetStringUTFRegion(jstr, 0, size, buffer.data());
48     sanitizeString(buffer.data());
49 
50     callback(buffer.data());
51 }
52 
android_os_Trace_nativeTraceCounter(JNIEnv * env,jclass,jlong tag,jstring nameStr,jlong value)53 static void android_os_Trace_nativeTraceCounter(JNIEnv* env, jclass,
54         jlong tag, jstring nameStr, jlong value) {
55     withString(env, nameStr, [tag, value](char* str) {
56         atrace_int64(tag, str, value);
57     });
58 }
59 
android_os_Trace_nativeTraceBegin(JNIEnv * env,jclass,jlong tag,jstring nameStr)60 static void android_os_Trace_nativeTraceBegin(JNIEnv* env, jclass,
61         jlong tag, jstring nameStr) {
62     withString(env, nameStr, [tag](char* str) {
63         atrace_begin(tag, str);
64     });
65 }
66 
android_os_Trace_nativeTraceEnd(JNIEnv *,jclass,jlong tag)67 static void android_os_Trace_nativeTraceEnd(JNIEnv*, jclass, jlong tag) {
68     atrace_end(tag);
69 }
70 
android_os_Trace_nativeAsyncTraceBegin(JNIEnv * env,jclass,jlong tag,jstring nameStr,jint cookie)71 static void android_os_Trace_nativeAsyncTraceBegin(JNIEnv* env, jclass,
72         jlong tag, jstring nameStr, jint cookie) {
73     withString(env, nameStr, [tag, cookie](char* str) {
74         atrace_async_begin(tag, str, cookie);
75     });
76 }
77 
android_os_Trace_nativeAsyncTraceEnd(JNIEnv * env,jclass,jlong tag,jstring nameStr,jint cookie)78 static void android_os_Trace_nativeAsyncTraceEnd(JNIEnv* env, jclass,
79         jlong tag, jstring nameStr, jint cookie) {
80     withString(env, nameStr, [tag, cookie](char* str) {
81         atrace_async_end(tag, str, cookie);
82     });
83 }
84 
android_os_Trace_nativeSetAppTracingAllowed(JNIEnv *,jclass,jboolean allowed)85 static void android_os_Trace_nativeSetAppTracingAllowed(JNIEnv*, jclass, jboolean allowed) {
86     atrace_update_tags();
87 }
88 
android_os_Trace_nativeSetTracingEnabled(JNIEnv *,jclass,jboolean enabled)89 static void android_os_Trace_nativeSetTracingEnabled(JNIEnv*, jclass, jboolean enabled) {
90     atrace_set_tracing_enabled(enabled);
91 }
92 
93 static const JNINativeMethod gTraceMethods[] = {
94     /* name, signature, funcPtr */
95     { "nativeSetAppTracingAllowed",
96             "(Z)V",
97             (void*)android_os_Trace_nativeSetAppTracingAllowed },
98     { "nativeSetTracingEnabled",
99             "(Z)V",
100             (void*)android_os_Trace_nativeSetTracingEnabled },
101 
102     // ----------- @FastNative  ----------------
103 
104     { "nativeTraceCounter",
105             "(JLjava/lang/String;J)V",
106             (void*)android_os_Trace_nativeTraceCounter },
107     { "nativeTraceBegin",
108             "(JLjava/lang/String;)V",
109             (void*)android_os_Trace_nativeTraceBegin },
110     { "nativeTraceEnd",
111             "(J)V",
112             (void*)android_os_Trace_nativeTraceEnd },
113     { "nativeAsyncTraceBegin",
114             "(JLjava/lang/String;I)V",
115             (void*)android_os_Trace_nativeAsyncTraceBegin },
116     { "nativeAsyncTraceEnd",
117             "(JLjava/lang/String;I)V",
118             (void*)android_os_Trace_nativeAsyncTraceEnd },
119 
120     // ----------- @CriticalNative  ----------------
121     { "nativeGetEnabledTags",
122             "()J",
123             (void*)atrace_get_enabled_tags },
124 };
125 
register_android_os_Trace(JNIEnv * env)126 int register_android_os_Trace(JNIEnv* env) {
127     int res = jniRegisterNativeMethods(env, "android/os/Trace",
128             gTraceMethods, NELEM(gTraceMethods));
129     LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
130 
131     return 0;
132 }
133 
134 } // namespace android
135