diff options
Diffstat (limited to 'protocols/Telegram/tdlib/td/example/java/td_jni.cpp')
-rw-r--r-- | protocols/Telegram/tdlib/td/example/java/td_jni.cpp | 128 |
1 files changed, 76 insertions, 52 deletions
diff --git a/protocols/Telegram/tdlib/td/example/java/td_jni.cpp b/protocols/Telegram/tdlib/td/example/java/td_jni.cpp index b9ba74a402..15c60a9545 100644 --- a/protocols/Telegram/tdlib/td/example/java/td_jni.cpp +++ b/protocols/Telegram/tdlib/td/example/java/td_jni.cpp @@ -1,11 +1,10 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include <td/telegram/Client.h> -#include <td/telegram/Log.h> #include <td/telegram/td_api.h> #include <td/tl/tl_jni_object.h> @@ -26,28 +25,35 @@ static td::td_api::object_ptr<td::td_api::Function> fetch_function(JNIEnv *env, return result; } -static td::Client *get_client(jlong client_id) { - return reinterpret_cast<td::Client *>(static_cast<std::uintptr_t>(client_id)); +static td::ClientManager *get_manager() { + return td::ClientManager::get_manager_singleton(); } -static jlong Client_createNativeClient(JNIEnv *env, jclass clazz) { - return static_cast<jlong>(reinterpret_cast<std::uintptr_t>(new td::Client())); +static jint Client_createNativeClient(JNIEnv *env, jclass clazz) { + return static_cast<jint>(get_manager()->create_client_id()); } -static void Client_nativeClientSend(JNIEnv *env, jclass clazz, jlong client_id, jlong id, jobject function) { - get_client(client_id)->send({static_cast<std::uint64_t>(id), fetch_function(env, function)}); +static void Client_nativeClientSend(JNIEnv *env, jclass clazz, jint client_id, jlong id, jobject function) { + get_manager()->send(static_cast<std::int32_t>(client_id), static_cast<std::uint64_t>(id), + fetch_function(env, function)); } -static jint Client_nativeClientReceive(JNIEnv *env, jclass clazz, jlong client_id, jlongArray ids, jobjectArray events, - jdouble timeout) { - auto client = get_client(client_id); - jsize events_size = env->GetArrayLength(ids); // ids and events size must be of equal size +static jint Client_nativeClientReceive(JNIEnv *env, jclass clazz, jintArray client_ids, jlongArray ids, + jobjectArray events, jdouble timeout) { + jsize events_size = env->GetArrayLength(ids); // client_ids, ids and events must be of equal size + if (events_size == 0) { + return 0; + } jsize result_size = 0; - auto response = client->receive(timeout); - while (response.object && result_size < events_size) { - jlong result_id = static_cast<jlong>(response.id); - env->SetLongArrayRegion(ids, result_size, 1, &result_id); + auto *manager = get_manager(); + auto response = manager->receive(timeout); + while (response.object) { + auto client_id = static_cast<jint>(response.client_id); + env->SetIntArrayRegion(client_ids, result_size, 1, &client_id); + + auto request_id = static_cast<jlong>(response.request_id); + env->SetLongArrayRegion(ids, result_size, 1, &request_id); jobject object; response.object->store(env, object); @@ -55,33 +61,21 @@ static jint Client_nativeClientReceive(JNIEnv *env, jclass clazz, jlong client_i env->DeleteLocalRef(object); result_size++; - response = client->receive(0); + if (result_size == events_size) { + break; + } + + response = manager->receive(0); } return result_size; } static jobject Client_nativeClientExecute(JNIEnv *env, jclass clazz, jobject function) { jobject result; - td::Client::execute({0, fetch_function(env, function)}).object->store(env, result); + td::ClientManager::execute(fetch_function(env, function))->store(env, result); return result; } -static void Client_destroyNativeClient(JNIEnv *env, jclass clazz, jlong client_id) { - delete get_client(client_id); -} - -static void Log_setVerbosityLevel(JNIEnv *env, jclass clazz, jint new_log_verbosity_level) { - td::Log::set_verbosity_level(static_cast<int>(new_log_verbosity_level)); -} - -static jboolean Log_setFilePath(JNIEnv *env, jclass clazz, jstring file_path) { - return td::Log::set_file_path(td::jni::from_jstring(env, file_path)) ? JNI_TRUE : JNI_FALSE; -} - -static void Log_setMaxFileSize(JNIEnv *env, jclass clazz, jlong max_file_size) { - td::Log::set_max_file_size(max_file_size); -} - static jstring Object_toString(JNIEnv *env, jobject object) { return td::jni::to_jstring(env, to_string(td::td_api::Object::fetch(env, object))); } @@ -92,17 +86,52 @@ static jstring Function_toString(JNIEnv *env, jobject object) { static constexpr jint JAVA_VERSION = JNI_VERSION_1_6; static JavaVM *java_vm; -static jclass log_class; +static jobject log_message_handler; -static void on_fatal_error(const char *error_message) { +static void on_log_message(int verbosity_level, const char *log_message) { auto env = td::jni::get_jni_env(java_vm, JAVA_VERSION); - jmethodID on_fatal_error_method = env->GetStaticMethodID(log_class, "onFatalError", "(Ljava/lang/String;)V"); - if (env && on_fatal_error_method) { - jstring error_str = td::jni::to_jstring(env.get(), error_message); - env->CallStaticVoidMethod(log_class, on_fatal_error_method, error_str); - if (error_str) { - env->DeleteLocalRef(error_str); + if (env == nullptr) { + return; + } + + jobject handler = env->NewLocalRef(log_message_handler); + if (!handler) { + return; + } + + jclass handler_class = env->GetObjectClass(handler); + if (handler_class) { + jmethodID on_log_message_method = env->GetMethodID(handler_class, "onLogMessage", "(ILjava/lang/String;)V"); + if (on_log_message_method) { + jstring log_message_str = td::jni::to_jstring(env.get(), log_message); + if (log_message_str) { + env->CallVoidMethod(handler, on_log_message_method, static_cast<jint>(verbosity_level), log_message_str); + env->DeleteLocalRef((jobject)log_message_str); + } + } + env->DeleteLocalRef((jobject)handler_class); + } + + env->DeleteLocalRef(handler); +} + +static void Client_nativeClientSetLogMessageHandler(JNIEnv *env, jclass clazz, jint max_verbosity_level, + jobject new_log_message_handler) { + if (log_message_handler) { + td::ClientManager::set_log_message_callback(0, nullptr); + jobject old_log_message_handler = log_message_handler; + log_message_handler = jobject(); + env->DeleteGlobalRef(old_log_message_handler); + } + + if (new_log_message_handler) { + log_message_handler = env->NewGlobalRef(new_log_message_handler); + if (!log_message_handler) { + // out of memory + return; } + + td::ClientManager::set_log_message_callback(static_cast<int>(max_verbosity_level), on_log_message); } } @@ -120,21 +149,17 @@ static jint register_native(JavaVM *vm) { }; auto client_class = td::jni::get_jclass(env, PACKAGE_NAME "/Client"); - log_class = td::jni::get_jclass(env, PACKAGE_NAME "/Log"); auto object_class = td::jni::get_jclass(env, PACKAGE_NAME "/TdApi$Object"); auto function_class = td::jni::get_jclass(env, PACKAGE_NAME "/TdApi$Function"); #define TD_OBJECT "L" PACKAGE_NAME "/TdApi$Object;" #define TD_FUNCTION "L" PACKAGE_NAME "/TdApi$Function;" - register_method(client_class, "createNativeClient", "()J", Client_createNativeClient); - register_method(client_class, "nativeClientSend", "(JJ" TD_FUNCTION ")V", Client_nativeClientSend); - register_method(client_class, "nativeClientReceive", "(J[J[" TD_OBJECT "D)I", Client_nativeClientReceive); + register_method(client_class, "createNativeClient", "()I", Client_createNativeClient); + register_method(client_class, "nativeClientSend", "(IJ" TD_FUNCTION ")V", Client_nativeClientSend); + register_method(client_class, "nativeClientReceive", "([I[J[" TD_OBJECT "D)I", Client_nativeClientReceive); register_method(client_class, "nativeClientExecute", "(" TD_FUNCTION ")" TD_OBJECT, Client_nativeClientExecute); - register_method(client_class, "destroyNativeClient", "(J)V", Client_destroyNativeClient); - - register_method(log_class, "setVerbosityLevel", "(I)V", Log_setVerbosityLevel); - register_method(log_class, "setFilePath", "(Ljava/lang/String;)Z", Log_setFilePath); - register_method(log_class, "setMaxFileSize", "(J)V", Log_setMaxFileSize); + register_method(client_class, "nativeClientSetLogMessageHandler", "(IL" PACKAGE_NAME "/Client$LogMessageHandler;)V", + Client_nativeClientSetLogMessageHandler); register_method(object_class, "toString", "()Ljava/lang/String;", Object_toString); @@ -145,7 +170,6 @@ static jint register_native(JavaVM *vm) { td::jni::init_vars(env, PACKAGE_NAME); td::td_api::Object::init_jni_vars(env, PACKAGE_NAME); td::td_api::Function::init_jni_vars(env, PACKAGE_NAME); - td::Log::set_fatal_error_callback(on_fatal_error); return JAVA_VERSION; } |