• 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_nativeGetEnabledTags(JNIEnv *,jclass)53 static jlong android_os_Trace_nativeGetEnabledTags(JNIEnv*, jclass) {
54     return atrace_get_enabled_tags();
55 }
56 
android_os_Trace_nativeTraceCounter(JNIEnv * env,jclass,jlong tag,jstring nameStr,jlong value)57 static void android_os_Trace_nativeTraceCounter(JNIEnv* env, jclass,
58         jlong tag, jstring nameStr, jlong value) {
59     withString(env, nameStr, [tag, value](char* str) {
60         atrace_int64(tag, str, value);
61     });
62 }
63 
android_os_Trace_nativeTraceBegin(JNIEnv * env,jclass,jlong tag,jstring nameStr)64 static void android_os_Trace_nativeTraceBegin(JNIEnv* env, jclass,
65         jlong tag, jstring nameStr) {
66     withString(env, nameStr, [tag](char* str) {
67         atrace_begin(tag, str);
68     });
69 }
70 
android_os_Trace_nativeTraceEnd(JNIEnv *,jclass,jlong tag)71 static void android_os_Trace_nativeTraceEnd(JNIEnv*, jclass, jlong tag) {
72     atrace_end(tag);
73 }
74 
android_os_Trace_nativeAsyncTraceBegin(JNIEnv * env,jclass,jlong tag,jstring nameStr,jint cookie)75 static void android_os_Trace_nativeAsyncTraceBegin(JNIEnv* env, jclass,
76         jlong tag, jstring nameStr, jint cookie) {
77     withString(env, nameStr, [tag, cookie](char* str) {
78         atrace_async_begin(tag, str, cookie);
79     });
80 }
81 
android_os_Trace_nativeAsyncTraceEnd(JNIEnv * env,jclass,jlong tag,jstring nameStr,jint cookie)82 static void android_os_Trace_nativeAsyncTraceEnd(JNIEnv* env, jclass,
83         jlong tag, jstring nameStr, jint cookie) {
84     withString(env, nameStr, [tag, cookie](char* str) {
85         atrace_async_end(tag, str, cookie);
86     });
87 }
88 
android_os_Trace_nativeSetAppTracingAllowed(JNIEnv *,jclass,jboolean allowed)89 static void android_os_Trace_nativeSetAppTracingAllowed(JNIEnv*, jclass, jboolean allowed) {
90     atrace_set_debuggable(allowed);
91 }
92 
android_os_Trace_nativeSetTracingEnabled(JNIEnv *,jclass,jboolean enabled)93 static void android_os_Trace_nativeSetTracingEnabled(JNIEnv*, jclass, jboolean enabled) {
94     atrace_set_tracing_enabled(enabled);
95 }
96 
97 static const JNINativeMethod gTraceMethods[] = {
98     /* name, signature, funcPtr */
99     { "nativeGetEnabledTags",
100             "()J",
101             (void*)android_os_Trace_nativeGetEnabledTags },
102     { "nativeSetAppTracingAllowed",
103             "(Z)V",
104             (void*)android_os_Trace_nativeSetAppTracingAllowed },
105     { "nativeSetTracingEnabled",
106             "(Z)V",
107             (void*)android_os_Trace_nativeSetTracingEnabled },
108 
109     // ----------- @FastNative  ----------------
110 
111     { "nativeTraceCounter",
112             "(JLjava/lang/String;J)V",
113             (void*)android_os_Trace_nativeTraceCounter },
114     { "nativeTraceBegin",
115             "(JLjava/lang/String;)V",
116             (void*)android_os_Trace_nativeTraceBegin },
117     { "nativeTraceEnd",
118             "(J)V",
119             (void*)android_os_Trace_nativeTraceEnd },
120     { "nativeAsyncTraceBegin",
121             "(JLjava/lang/String;I)V",
122             (void*)android_os_Trace_nativeAsyncTraceBegin },
123     { "nativeAsyncTraceEnd",
124             "(JLjava/lang/String;I)V",
125             (void*)android_os_Trace_nativeAsyncTraceEnd },
126 };
127 
register_android_os_Trace(JNIEnv * env)128 int register_android_os_Trace(JNIEnv* env) {
129     int res = jniRegisterNativeMethods(env, "android/os/Trace",
130             gTraceMethods, NELEM(gTraceMethods));
131     LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
132 
133     return 0;
134 }
135 
136 } // namespace android
137