blob: 3bec24d1e0023971fb078b53730f18c29eb28376 [file] [log] [blame]
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "src/android_sdk/jni/dev_perfetto_sdk_PerfettoTrackEventExtra.h"
#include <jni.h>
#include "src/android_sdk/jni/macros.h"
#include "src/android_sdk/nativehelper/JNIHelp.h"
#include "src/android_sdk/nativehelper/scoped_utf_chars.h"
#include "src/android_sdk/perfetto_sdk_for_jni/tracing_sdk.h"
#include <list>
namespace perfetto {
namespace jni {
template <typename T>
inline static T* toPointer(jlong ptr) {
return reinterpret_cast<T*>(static_cast<uintptr_t>(ptr));
}
template <typename T>
inline static jlong toJLong(T* ptr) {
return static_cast<jlong>(reinterpret_cast<uintptr_t>(ptr));
}
/**
* @brief A thread-safe utility class for converting Java UTF-16 strings to
* ASCII in JNI environment.
*
* StringBuffer provides efficient conversion of Java strings to ASCII with
* optimized memory handling. It uses a two-tiered buffering strategy:
* 1. A fast path using pre-allocated thread-local buffers for strings up to 128
* characters
* 2. A fallback path using dynamic allocation for longer strings
*
* Non-ASCII characters (>255) are replaced with '?' during conversion. The
* class maintains thread safety through thread-local storage and provides
* zero-copy string views for optimal performance.
*
* Memory Management:
* - Uses fixed-size thread-local buffers for both UTF-16 and ASCII characters
* - Overflow strings are stored in a thread-local list to maintain valid string
* views
* - Avoids unnecessary allocations in the common case of small strings
*
* Usage example:
* @code
* JNIEnv* env = ...;
* jstring java_string = ...;
* std::string_view ascii = StringBuffer::utf16_to_ascii(env, java_string);
* // Use the ASCII string...
* StringBuffer::reset(); // Clean up when done
* @endcode
*
* Thread Safety: All methods are thread-safe due to thread-local storage.
*/
class StringBuffer {
private:
static constexpr size_t BASE_SIZE = 128;
// Temporarily stores the UTF-16 characters retrieved from the Java
// string before they are converted to ASCII.
static thread_local inline char char_buffer[BASE_SIZE];
// For fast-path conversions when the resulting ASCII string fits within
// the pre-allocated space. All ascii strings in a trace event will be stored
// here until emitted.
static thread_local inline jchar jchar_buffer[BASE_SIZE];
// When the fast-path conversion is not possible (because char_buffer
// doesn't have enough space), the converted ASCII string is stored
// in this list. We use list here to avoid moving the strings on resize
// with vector. This way, we can give out string_views from the stored
// strings. The additional overhead from list node allocations is fine cos we
// are already in an extremely unlikely path here and there are other bigger
// problems if here.
static thread_local inline std::list<std::string> overflow_strings;
// current offset into the char_buffer.
static thread_local inline size_t current_offset{0};
// This allows us avoid touching the overflow_strings directly in the fast
// path. Touching it causes some thread local init routine to run which shows
// up in profiles.
static thread_local inline bool is_overflow_strings_empty = true;
static void copy_utf16_to_ascii(const jchar* src,
size_t len,
char* dst,
JNIEnv* env,
jstring str) {
std::transform(src, src + len, dst, [](jchar c) {
return (c <= 0xFF) ? static_cast<char>(c) : '?';
});
if (src != jchar_buffer) {
// We hit the slow path to populate src, so we have to release.
env->ReleaseStringCritical(str, src);
}
}
public:
static void reset() {
if (!is_overflow_strings_empty) {
overflow_strings.clear();
is_overflow_strings_empty = true;
}
current_offset = 0;
}
// Converts a Java string (jstring) to an ASCII string_view. Characters
// outside the ASCII range (0-255) are replaced with '?'.
//
// @param env The JNI environment.
// @param val The Java string to convert.
// @return A string_view representing the ASCII version of the string.
// Returns an empty string_view if the input is null or empty.
static std::string_view utf16_to_ascii(JNIEnv* env, jstring val) {
if (!val)
return "";
const jsize len = env->GetStringLength(val);
if (len == 0)
return "";
const jchar* temp_buffer;
// Fast path: Enough space in jchar_buffer
if (static_cast<size_t>(len) <= BASE_SIZE) {
env->GetStringRegion(val, 0, len, jchar_buffer);
temp_buffer = jchar_buffer;
} else {
// Slow path: Fallback to asking ART for the string which will likely
// allocate and return a copy.
temp_buffer = env->GetStringCritical(val, nullptr);
}
const size_t next_offset = current_offset + len + 1;
// Fast path: Enough space in char_buffer
if (BASE_SIZE > next_offset) {
copy_utf16_to_ascii(temp_buffer, len, char_buffer + current_offset, env,
val);
char_buffer[current_offset + len] = '\0';
auto res = std::string_view(char_buffer + current_offset, len);
current_offset = next_offset;
return res;
} else {
// Slow path: Not enough space in char_buffer. Use overflow_strings.
// This will cause a string alloc but should be very unlikely to hit.
std::string& str = overflow_strings.emplace_back(len + 1, '\0');
copy_utf16_to_ascii(temp_buffer, len, str.data(), env, val);
is_overflow_strings_empty = false;
return std::string_view(str);
}
}
};
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgInt64_init(
JNIEnv* env,
jclass,
jstring name) {
return toJLong(new sdk_for_jni::DebugArg<int64_t>(
StringBuffer::utf16_to_ascii(env, name).data()));
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgBool_init(
JNIEnv* env,
jclass,
jstring name) {
return toJLong(new sdk_for_jni::DebugArg<bool>(
StringBuffer::utf16_to_ascii(env, name).data()));
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgDouble_init(
JNIEnv* env,
jclass,
jstring name) {
return toJLong(new sdk_for_jni::DebugArg<double>(
StringBuffer::utf16_to_ascii(env, name).data()));
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgString_init(
JNIEnv* env,
jclass,
jstring name) {
return toJLong(new sdk_for_jni::DebugArg<const char*>(
StringBuffer::utf16_to_ascii(env, name).data()));
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgInt64_delete() {
return toJLong(&sdk_for_jni::DebugArg<int64_t>::delete_arg);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgBool_delete() {
return toJLong(&sdk_for_jni::DebugArg<bool>::delete_arg);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgDouble_delete() {
return toJLong(&sdk_for_jni::DebugArg<double>::delete_arg);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgString_delete() {
return toJLong(&sdk_for_jni::DebugArg<const char*>::delete_arg);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgInt64_get_extra_ptr(
jlong ptr) {
sdk_for_jni::DebugArg<int64_t>* arg =
toPointer<sdk_for_jni::DebugArg<int64_t>>(ptr);
return toJLong(arg->get());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgBool_get_extra_ptr(
jlong ptr) {
sdk_for_jni::DebugArg<bool>* arg =
toPointer<sdk_for_jni::DebugArg<bool>>(ptr);
return toJLong(arg->get());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgDouble_get_extra_ptr(
jlong ptr) {
sdk_for_jni::DebugArg<double>* arg =
toPointer<sdk_for_jni::DebugArg<double>>(ptr);
return toJLong(arg->get());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraArgString_get_extra_ptr(
jlong ptr) {
sdk_for_jni::DebugArg<const char*>* arg =
toPointer<sdk_for_jni::DebugArg<const char*>>(ptr);
return toJLong(arg->get());
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraArgInt64_set_value(
jlong ptr,
jlong val) {
sdk_for_jni::DebugArg<int64_t>* arg =
toPointer<sdk_for_jni::DebugArg<int64_t>>(ptr);
arg->set_value(val);
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraArgBool_set_value(
jlong ptr,
jboolean val) {
sdk_for_jni::DebugArg<bool>* arg =
toPointer<sdk_for_jni::DebugArg<bool>>(ptr);
arg->set_value(val);
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraArgDouble_set_value(
jlong ptr,
jdouble val) {
sdk_for_jni::DebugArg<double>* arg =
toPointer<sdk_for_jni::DebugArg<double>>(ptr);
arg->set_value(val);
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraArgString_set_value(
JNIEnv* env,
jclass,
jlong ptr,
jstring val) {
sdk_for_jni::DebugArg<const char*>* arg =
toPointer<sdk_for_jni::DebugArg<const char*>>(ptr);
arg->set_value(StringBuffer::utf16_to_ascii(env, val).data());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldInt64_init() {
return toJLong(new sdk_for_jni::ProtoField<int64_t>());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldDouble_init() {
return toJLong(new sdk_for_jni::ProtoField<double>());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldString_init() {
return toJLong(new sdk_for_jni::ProtoField<const char*>());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldNested_init() {
return toJLong(new sdk_for_jni::ProtoFieldNested());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldInt64_delete() {
return toJLong(&sdk_for_jni::ProtoField<int64_t>::delete_field);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldDouble_delete() {
return toJLong(&sdk_for_jni::ProtoField<double>::delete_field);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldString_delete() {
return toJLong(&sdk_for_jni::ProtoField<const char*>::delete_field);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldNested_delete() {
return toJLong(&sdk_for_jni::ProtoFieldNested::delete_field);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldInt64_get_extra_ptr(
jlong ptr) {
sdk_for_jni::ProtoField<int64_t>* field =
toPointer<sdk_for_jni::ProtoField<int64_t>>(ptr);
return toJLong(field->get());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldDouble_get_extra_ptr(
jlong ptr) {
sdk_for_jni::ProtoField<double>* field =
toPointer<sdk_for_jni::ProtoField<double>>(ptr);
return toJLong(field->get());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldString_get_extra_ptr(
jlong ptr) {
sdk_for_jni::ProtoField<const char*>* field =
toPointer<sdk_for_jni::ProtoField<const char*>>(ptr);
return toJLong(field->get());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFieldNested_get_extra_ptr(
jlong ptr) {
sdk_for_jni::ProtoFieldNested* field =
toPointer<sdk_for_jni::ProtoFieldNested>(ptr);
return toJLong(field->get());
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraFieldInt64_set_value(
jlong ptr,
jlong id,
jlong val) {
sdk_for_jni::ProtoField<int64_t>* field =
toPointer<sdk_for_jni::ProtoField<int64_t>>(ptr);
field->set_value(id, val);
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraFieldDouble_set_value(
jlong ptr,
jlong id,
jdouble val) {
sdk_for_jni::ProtoField<double>* field =
toPointer<sdk_for_jni::ProtoField<double>>(ptr);
field->set_value(id, val);
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraFieldString_set_value(
JNIEnv* env,
jclass,
jlong ptr,
jlong id,
jstring val) {
sdk_for_jni::ProtoField<const char*>* field =
toPointer<sdk_for_jni::ProtoField<const char*>>(ptr);
field->set_value(id, StringBuffer::utf16_to_ascii(env, val).data());
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraFieldNested_add_field(
jlong field_ptr,
jlong arg_ptr) {
sdk_for_jni::ProtoFieldNested* field =
toPointer<sdk_for_jni::ProtoFieldNested>(field_ptr);
field->add_field(toPointer<PerfettoTeHlProtoField>(arg_ptr));
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraFieldNested_set_id(
jlong ptr,
jlong id) {
sdk_for_jni::ProtoFieldNested* field =
toPointer<sdk_for_jni::ProtoFieldNested>(ptr);
field->set_id(id);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFlow_init() {
return toJLong(new sdk_for_jni::Flow());
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraFlow_set_process_flow(
jlong ptr,
jlong id) {
sdk_for_jni::Flow* flow = toPointer<sdk_for_jni::Flow>(ptr);
flow->set_process_flow(id);
}
static void
dev_perfetto_sdk_PerfettoTrackEventExtraFlow_set_process_terminating_flow(
jlong ptr,
jlong id) {
sdk_for_jni::Flow* flow = toPointer<sdk_for_jni::Flow>(ptr);
flow->set_process_terminating_flow(id);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFlow_delete() {
return toJLong(&sdk_for_jni::Flow::delete_flow);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraFlow_get_extra_ptr(
jlong ptr) {
sdk_for_jni::Flow* flow = toPointer<sdk_for_jni::Flow>(ptr);
return toJLong(flow->get());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraNamedTrack_init(
JNIEnv* env,
jclass,
jlong id,
jstring name,
jlong parent_uuid) {
return toJLong(new sdk_for_jni::NamedTrack(
id, parent_uuid, StringBuffer::utf16_to_ascii(env, name).data()));
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraNamedTrack_delete() {
return toJLong(&sdk_for_jni::NamedTrack::delete_track);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraNamedTrack_get_extra_ptr(
jlong ptr) {
sdk_for_jni::NamedTrack* track = toPointer<sdk_for_jni::NamedTrack>(ptr);
return toJLong(track->get());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraCounterTrack_init(
JNIEnv* env,
jclass,
jstring name,
jlong parent_uuid) {
return toJLong(new sdk_for_jni::RegisteredTrack(
1, parent_uuid, StringBuffer::utf16_to_ascii(env, name).data(), true));
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraCounterTrack_delete() {
return toJLong(&sdk_for_jni::RegisteredTrack::delete_track);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraCounterTrack_get_extra_ptr(
jlong ptr) {
sdk_for_jni::RegisteredTrack* track =
toPointer<sdk_for_jni::RegisteredTrack>(ptr);
return toJLong(track->get());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraCounterInt64_init() {
return toJLong(new sdk_for_jni::Counter<int64_t>());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraCounterInt64_delete() {
return toJLong(&sdk_for_jni::Counter<int64_t>::delete_counter);
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraCounterInt64_set_value(
jlong ptr,
jlong val) {
sdk_for_jni::Counter<int64_t>* counter =
toPointer<sdk_for_jni::Counter<int64_t>>(ptr);
counter->set_value(val);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraCounterInt64_get_extra_ptr(
jlong ptr) {
sdk_for_jni::Counter<int64_t>* counter =
toPointer<sdk_for_jni::Counter<int64_t>>(ptr);
return toJLong(counter->get());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraCounterDouble_init() {
return toJLong(new sdk_for_jni::Counter<double>());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraCounterDouble_delete() {
return toJLong(&sdk_for_jni::Counter<double>::delete_counter);
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraCounterDouble_set_value(
jlong ptr,
jdouble val) {
sdk_for_jni::Counter<double>* counter =
toPointer<sdk_for_jni::Counter<double>>(ptr);
counter->set_value(val);
}
static jlong
dev_perfetto_sdk_PerfettoTrackEventExtraCounterDouble_get_extra_ptr(jlong ptr) {
sdk_for_jni::Counter<double>* counter =
toPointer<sdk_for_jni::Counter<double>>(ptr);
return toJLong(counter->get());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtra_init() {
return toJLong(new sdk_for_jni::Extra());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtra_delete() {
return toJLong(&sdk_for_jni::Extra::delete_extra);
}
static void dev_perfetto_sdk_PerfettoTrackEventExtra_add_arg(jlong extra_ptr,
jlong arg_ptr) {
sdk_for_jni::Extra* extra = toPointer<sdk_for_jni::Extra>(extra_ptr);
extra->push_extra(toPointer<PerfettoTeHlExtra>(arg_ptr));
}
static void dev_perfetto_sdk_PerfettoTrackEventExtra_clear_args(jlong ptr) {
sdk_for_jni::Extra* extra = toPointer<sdk_for_jni::Extra>(ptr);
extra->clear_extras();
}
static void dev_perfetto_sdk_PerfettoTrackEventExtra_emit(JNIEnv* env,
jclass,
jint type,
jlong cat_ptr,
jstring name,
jlong extra_ptr) {
sdk_for_jni::Category* category = toPointer<sdk_for_jni::Category>(cat_ptr);
trace_event(type, category->get(),
StringBuffer::utf16_to_ascii(env, name).data(),
toPointer<sdk_for_jni::Extra>(extra_ptr));
StringBuffer::reset();
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraProto_init() {
return toJLong(new sdk_for_jni::Proto());
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraProto_delete() {
return toJLong(&sdk_for_jni::Proto::delete_proto);
}
static jlong dev_perfetto_sdk_PerfettoTrackEventExtraProto_get_extra_ptr(
jlong ptr) {
sdk_for_jni::Proto* proto = toPointer<sdk_for_jni::Proto>(ptr);
return toJLong(proto->get());
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraProto_add_field(
long proto_ptr,
jlong arg_ptr) {
sdk_for_jni::Proto* proto = toPointer<sdk_for_jni::Proto>(proto_ptr);
proto->add_field(toPointer<PerfettoTeHlProtoField>(arg_ptr));
}
static void dev_perfetto_sdk_PerfettoTrackEventExtraProto_clear_fields(
jlong ptr) {
sdk_for_jni::Proto* proto = toPointer<sdk_for_jni::Proto>(ptr);
proto->clear_fields();
}
static const JNINativeMethod gExtraMethods[] = {
{"native_init", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtra_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtra_delete},
{"native_add_arg", "(JJ)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtra_add_arg},
{"native_clear_args", "(J)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtra_clear_args},
{"native_emit", "(IJLjava/lang/String;J)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtra_emit}};
static const JNINativeMethod gProtoMethods[] = {
{"native_init", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraProto_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraProto_delete},
{"native_get_extra_ptr", "(J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraProto_get_extra_ptr},
{"native_add_field", "(JJ)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraProto_add_field},
{"native_clear_fields", "(J)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraProto_clear_fields}};
static const JNINativeMethod gArgInt64Methods[] = {
{"native_init", "(Ljava/lang/String;)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgInt64_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgInt64_delete},
{"native_get_extra_ptr", "(J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgInt64_get_extra_ptr},
{"native_set_value", "(JJ)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgInt64_set_value},
};
static const JNINativeMethod gArgBoolMethods[] = {
{"native_init", "(Ljava/lang/String;)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgBool_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgBool_delete},
{"native_get_extra_ptr", "(J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgBool_get_extra_ptr},
{"native_set_value", "(JZ)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgBool_set_value},
};
static const JNINativeMethod gArgDoubleMethods[] = {
{"native_init", "(Ljava/lang/String;)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgDouble_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgDouble_delete},
{"native_get_extra_ptr", "(J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgDouble_get_extra_ptr},
{"native_set_value", "(JD)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgDouble_set_value},
};
static const JNINativeMethod gArgStringMethods[] = {
{"native_init", "(Ljava/lang/String;)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgString_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgString_delete},
{"native_get_extra_ptr", "(J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgString_get_extra_ptr},
{"native_set_value", "(JLjava/lang/String;)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraArgString_set_value},
};
static const JNINativeMethod gFieldInt64Methods[] = {
{"native_init", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldInt64_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldInt64_delete},
{"native_get_extra_ptr", "(J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldInt64_get_extra_ptr},
{"native_set_value", "(JJJ)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldInt64_set_value},
};
static const JNINativeMethod gFieldDoubleMethods[] = {
{"native_init", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldDouble_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldDouble_delete},
{"native_get_extra_ptr", "(J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldDouble_get_extra_ptr},
{"native_set_value", "(JJD)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldDouble_set_value},
};
static const JNINativeMethod gFieldStringMethods[] = {
{"native_init", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldString_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldString_delete},
{"native_get_extra_ptr", "(J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldString_get_extra_ptr},
{"native_set_value", "(JJLjava/lang/String;)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldString_set_value},
};
static const JNINativeMethod gFieldNestedMethods[] = {
{"native_init", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldNested_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldNested_delete},
{"native_get_extra_ptr", "(J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldNested_get_extra_ptr},
{"native_add_field", "(JJ)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldNested_add_field},
{"native_set_id", "(JJ)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFieldNested_set_id}};
static const JNINativeMethod gFlowMethods[] = {
{"native_init", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFlow_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFlow_delete},
{"native_set_process_flow", "(JJ)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFlow_set_process_flow},
{"native_set_process_terminating_flow", "(JJ)V",
(void*)
dev_perfetto_sdk_PerfettoTrackEventExtraFlow_set_process_terminating_flow},
{"native_get_extra_ptr", "(J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraFlow_get_extra_ptr},
};
static const JNINativeMethod gNamedTrackMethods[] = {
{"native_init", "(JLjava/lang/String;J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraNamedTrack_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraNamedTrack_delete},
{"native_get_extra_ptr", "(J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraNamedTrack_get_extra_ptr},
};
static const JNINativeMethod gCounterTrackMethods[] = {
{"native_init", "(Ljava/lang/String;J)J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraCounterTrack_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraCounterTrack_delete},
{"native_get_extra_ptr", "(J)J",
(void*)
dev_perfetto_sdk_PerfettoTrackEventExtraCounterTrack_get_extra_ptr}};
static const JNINativeMethod gCounterInt64Methods[] = {
{"native_init", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraCounterInt64_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraCounterInt64_delete},
{"native_set_value", "(JJ)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraCounterInt64_set_value},
{"native_get_extra_ptr", "(J)J",
(void*)
dev_perfetto_sdk_PerfettoTrackEventExtraCounterInt64_get_extra_ptr}};
static const JNINativeMethod gCounterDoubleMethods[] = {
{"native_init", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraCounterDouble_init},
{"native_delete", "()J",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraCounterDouble_delete},
{"native_set_value", "(JD)V",
(void*)dev_perfetto_sdk_PerfettoTrackEventExtraCounterDouble_set_value},
{"native_get_extra_ptr", "(J)J",
(void*)
dev_perfetto_sdk_PerfettoTrackEventExtraCounterDouble_get_extra_ptr}};
int register_dev_perfetto_sdk_PerfettoTrackEventExtra(JNIEnv* env) {
int res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$ArgInt64"),
gArgInt64Methods, NELEM(gArgInt64Methods));
LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register arg int64 native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$ArgBool"),
gArgBoolMethods, NELEM(gArgBoolMethods));
LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register arg bool native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$ArgDouble"),
gArgDoubleMethods, NELEM(gArgDoubleMethods));
LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register arg double native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$ArgString"),
gArgStringMethods, NELEM(gArgStringMethods));
LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register arg string native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$FieldInt64"),
gFieldInt64Methods, NELEM(gFieldInt64Methods));
LOG_ALWAYS_FATAL_IF(res < 0,
"Unable to register field int64 native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$FieldDouble"),
gFieldDoubleMethods, NELEM(gFieldDoubleMethods));
LOG_ALWAYS_FATAL_IF(res < 0,
"Unable to register field double native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$FieldString"),
gFieldStringMethods, NELEM(gFieldStringMethods));
LOG_ALWAYS_FATAL_IF(res < 0,
"Unable to register field string native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$FieldNested"),
gFieldNestedMethods, NELEM(gFieldNestedMethods));
LOG_ALWAYS_FATAL_IF(res < 0,
"Unable to register field nested native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME("dev/perfetto/sdk/PerfettoTrackEventExtra"),
gExtraMethods, NELEM(gExtraMethods));
LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register extra native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$Proto"),
gProtoMethods, NELEM(gProtoMethods));
LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register proto native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$Flow"),
gFlowMethods, NELEM(gFlowMethods));
LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register flow native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$NamedTrack"),
gNamedTrackMethods, NELEM(gNamedTrackMethods));
LOG_ALWAYS_FATAL_IF(res < 0,
"Unable to register named track native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$CounterTrack"),
gCounterTrackMethods, NELEM(gCounterTrackMethods));
LOG_ALWAYS_FATAL_IF(res < 0,
"Unable to register counter track native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$CounterInt64"),
gCounterInt64Methods, NELEM(gCounterInt64Methods));
LOG_ALWAYS_FATAL_IF(res < 0,
"Unable to register counter int64 native methods.");
res = jniRegisterNativeMethods(
env,
TO_MAYBE_JAR_JAR_CLASS_NAME(
"dev/perfetto/sdk/PerfettoTrackEventExtra$CounterDouble"),
gCounterDoubleMethods, NELEM(gCounterDoubleMethods));
LOG_ALWAYS_FATAL_IF(res < 0,
"Unable to register counter double native methods.");
return 0;
}
} // namespace jni
} // namespace perfetto