From e4a555d8e146994b7fc99c8f0c0f6b4ca8af1495 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 8 Dec 2022 12:33:42 +0300 Subject: we don't need this code --- .../Telegram/tdlib/td/example/java/.gitignore | 5 - .../Telegram/tdlib/td/example/java/CMakeLists.txt | 124 ---- protocols/Telegram/tdlib/td/example/java/README.md | 43 -- .../example/java/org/drinkless/tdlib/Client.java | 242 -------- .../java/org/drinkless/tdlib/example/Example.java | 685 --------------------- .../Telegram/tdlib/td/example/java/td_jni.cpp | 182 ------ 6 files changed, 1281 deletions(-) delete mode 100644 protocols/Telegram/tdlib/td/example/java/.gitignore delete mode 100644 protocols/Telegram/tdlib/td/example/java/CMakeLists.txt delete mode 100644 protocols/Telegram/tdlib/td/example/java/README.md delete mode 100644 protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/Client.java delete mode 100644 protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java delete mode 100644 protocols/Telegram/tdlib/td/example/java/td_jni.cpp (limited to 'protocols/Telegram/tdlib/td/example/java') diff --git a/protocols/Telegram/tdlib/td/example/java/.gitignore b/protocols/Telegram/tdlib/td/example/java/.gitignore deleted file mode 100644 index 8f846b80d9..0000000000 --- a/protocols/Telegram/tdlib/td/example/java/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -**/*build/ -bin/ -docs/ -org/drinkless/tdlib/TdApi.java -td/ diff --git a/protocols/Telegram/tdlib/td/example/java/CMakeLists.txt b/protocols/Telegram/tdlib/td/example/java/CMakeLists.txt deleted file mode 100644 index 576eee2cfc..0000000000 --- a/protocols/Telegram/tdlib/td/example/java/CMakeLists.txt +++ /dev/null @@ -1,124 +0,0 @@ -cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) - -if (POLICY CMP0065) - # do not export symbols from executables - # affects compiler checks in project(), so must be set before it - cmake_policy(SET CMP0065 NEW) -endif() - -project(TdJavaExample VERSION 1.0 LANGUAGES CXX) - -if (POLICY CMP0054) - # do not expand quoted arguments - cmake_policy(SET CMP0054 NEW) -endif() -if (POLICY CMP0060) - # link libraries by full path - cmake_policy(SET CMP0060 NEW) -endif() -if (POLICY CMP0074) - # use environment variables to find libraries - cmake_policy(SET CMP0074 NEW) -endif() - -find_package(Td REQUIRED) - -if (NOT JNI_FOUND) - find_package(JNI REQUIRED) -endif() -message(STATUS "Found JNI: ${JNI_INCLUDE_DIRS} ${JNI_LIBRARIES}") - -if (NOT Java_FOUND) - find_package(Java REQUIRED) -endif() -message(STATUS "Found Java: ${Java_JAVAC_EXECUTABLE} ${Java_JAVADOC_EXECUTABLE}") - -# Generating TdApi.java -find_program(PHP_EXECUTABLE php) -if ((CMAKE_SYSTEM_NAME MATCHES "FreeBSD") AND (CMAKE_SYSTEM_VERSION MATCHES "HBSD")) - set(PHP_EXECUTABLE "PHP_EXECUTABLE-NOTFOUND") -endif() - -set(TD_API_JAVA_PACKAGE "org/drinkless/tdlib") -set(TD_API_JAVA_PATH ${CMAKE_CURRENT_SOURCE_DIR}) -set(TD_API_TLO_PATH ${CMAKE_CURRENT_SOURCE_DIR}/td/bin/td/generate/scheme/td_api.tlo) -set(TD_API_TL_PATH ${CMAKE_CURRENT_SOURCE_DIR}/td/bin/td/generate/scheme/td_api.tl) -set(JAVADOC_TL_DOCUMENTATION_GENERATOR_PATH ${CMAKE_CURRENT_SOURCE_DIR}/td/bin/td/generate/JavadocTlDocumentationGenerator.php) -set(GENERATE_JAVA_API_CMD ${CMAKE_CURRENT_SOURCE_DIR}/td/bin/td_generate_java_api TdApi ${TD_API_TLO_PATH} ${TD_API_JAVA_PATH} ${TD_API_JAVA_PACKAGE}) -if (PHP_EXECUTABLE) - set(GENERATE_JAVA_API_CMD ${GENERATE_JAVA_API_CMD} && ${PHP_EXECUTABLE} ${JAVADOC_TL_DOCUMENTATION_GENERATOR_PATH} ${TD_API_TL_PATH} ${TD_API_JAVA_PATH}/${TD_API_JAVA_PACKAGE}/TdApi.java) -endif() - -add_custom_target(td_generate_java_api - COMMAND ${GENERATE_JAVA_API_CMD} - COMMENT "Generating Java TDLib API source files" - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/td/bin/td_generate_java_api ${TD_API_TLO_PATH} ${TD_API_TL_PATH} ${JAVADOC_TL_DOCUMENTATION_GENERATOR_PATH} -) - -set(JAVA_SOURCE_PATH "${TD_API_JAVA_PATH}/${TD_API_JAVA_PACKAGE}") -get_filename_component(JAVA_OUTPUT_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin REALPATH BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}") -file(MAKE_DIRECTORY ${JAVA_OUTPUT_DIRECTORY}) -add_custom_target(build_java - COMMAND ${Java_JAVAC_EXECUTABLE} -encoding UTF-8 -d ${JAVA_OUTPUT_DIRECTORY} ${JAVA_SOURCE_PATH}/example/Example.java ${JAVA_SOURCE_PATH}/Client.java ${JAVA_SOURCE_PATH}/TdApi.java - COMMENT "Building Java code" - DEPENDS td_generate_java_api -) - -add_custom_target(generate_javadoc - COMMAND ${Java_JAVADOC_EXECUTABLE} -encoding UTF-8 -charset UTF-8 -d ${JAVA_OUTPUT_DIRECTORY}/../docs org.drinkless.tdlib - WORKING_DIRECTORY ${TD_API_JAVA_PATH} - COMMENT "Generating Javadoc documentation" - DEPENDS td_generate_java_api -) - -# Building shared library -add_library(tdjni SHARED - td_jni.cpp -) -target_include_directories(tdjni PRIVATE ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2}) -target_link_libraries(tdjni PRIVATE Td::TdStatic ${JAVA_JVM_LIBRARY}) -target_compile_definitions(tdjni PRIVATE PACKAGE_NAME="${TD_API_JAVA_PACKAGE}") - -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(GCC 1) -elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CLANG 1) -elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") - set(INTEL 1) -elseif (NOT MSVC) - message(FATAL_ERROR "Compiler isn't supported") -endif() - -include(CheckCXXCompilerFlag) - -if (GCC OR CLANG OR INTEL) - if (WIN32 AND INTEL) - set(STD14_FLAG /Qstd=c++14) - else() - set(STD14_FLAG -std=c++14) - endif() - check_cxx_compiler_flag(${STD14_FLAG} HAVE_STD14) - if (NOT HAVE_STD14) - string(REPLACE "c++14" "c++1y" STD14_FLAG "${STD14_FLAG}") - check_cxx_compiler_flag(${STD14_FLAG} HAVE_STD1Y) - set(HAVE_STD14 ${HAVE_STD1Y}) - endif() - - target_compile_options(tdjni PRIVATE "${STD14_FLAG}") -elseif (MSVC) - set(HAVE_STD14 MSVC_VERSION>=1900) -endif() - -if (NOT HAVE_STD14) - message(FATAL_ERROR "No C++14 support in the compiler. Please upgrade the compiler.") -endif() - -add_dependencies(tdjni td_generate_java_api build_java generate_javadoc) - -install(TARGETS tdjni - LIBRARY DESTINATION bin - RUNTIME DESTINATION bin -) -if (MSVC AND VCPKG_TOOLCHAIN) - install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$/" DESTINATION bin FILES_MATCHING PATTERN "*.dll" PATTERN "*.pdb") -endif() diff --git a/protocols/Telegram/tdlib/td/example/java/README.md b/protocols/Telegram/tdlib/td/example/java/README.md deleted file mode 100644 index 4c7df1916d..0000000000 --- a/protocols/Telegram/tdlib/td/example/java/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# TDLib Java example - -To run this example, you will need installed JDK >= 1.6. -For Javadoc documentation generation PHP is needed. - -You can find complete build instructions for your operating system at https://tdlib.github.io/td/build.html?language=Java. - -In general, the build process looks as follows. - -TDLib should be prebuilt with JNI bindings and installed to local subdirectory `td/` as follows: -``` -cd -mkdir jnibuild -cd jnibuild -cmake -DCMAKE_BUILD_TYPE=Release -DTD_ENABLE_JNI=ON -DCMAKE_INSTALL_PREFIX:PATH=../example/java/td .. -cmake --build . --target install -``` -If you want to compile TDLib for 32-bit/64-bit Java on Windows using MSVC, you will also need to add `-A Win32`/`-A x64` option to CMake. - -In Windows, use vcpkg toolchain file by adding parameter -DCMAKE_TOOLCHAIN_FILE=/scripts/buildsystems/vcpkg.cmake - -Then you can build this example: -``` -cd /example/java -mkdir build -cd build -cmake -DCMAKE_BUILD_TYPE=Release -DTd_DIR=/example/java/td/lib/cmake/Td -DCMAKE_INSTALL_PREFIX:PATH=.. .. -cmake --build . --target install -``` - -Compiled TDLib shared library and Java example after that will be placed in bin/ and Javadoc documentation in `docs/`. - -Now you can run Java example: -``` -cd /example/java/bin -java '-Djava.library.path=.' org/drinkless/tdlib/example/Example -``` - -If you receive "Could NOT find JNI ..." error from CMake, you need to specify to CMake path to the installed JDK, for example, "-DJAVA_HOME=/usr/lib/jvm/java-8-oracle/". - -If you receive java.lang.UnsatisfiedLinkError with "Can't find dependent libraries", you may also need to copy some dependent shared OpenSSL and zlib libraries to `bin/`. - -Make sure that you compiled the example for the same architecture as your JVM. diff --git a/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/Client.java b/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/Client.java deleted file mode 100644 index 0a58bb45a7..0000000000 --- a/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/Client.java +++ /dev/null @@ -1,242 +0,0 @@ -// -// 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) -// -package org.drinkless.tdlib; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - -/** - * Main class for interaction with the TDLib. - */ -public final class Client { - static { - try { - System.loadLibrary("tdjni"); - } catch (UnsatisfiedLinkError e) { - e.printStackTrace(); - } - } - - /** - * Interface for handler for results of queries to TDLib and incoming updates from TDLib. - */ - public interface ResultHandler { - /** - * Callback called on result of query to TDLib or incoming update from TDLib. - * - * @param object Result of query or update of type TdApi.Update about new events. - */ - void onResult(TdApi.Object object); - } - - /** - * Interface for handler of exceptions thrown while invoking ResultHandler. - * By default, all such exceptions are ignored. - * All exceptions thrown from ExceptionHandler are ignored. - */ - public interface ExceptionHandler { - /** - * Callback called on exceptions thrown while invoking ResultHandler. - * - * @param e Exception thrown by ResultHandler. - */ - void onException(Throwable e); - } - - /** - * Interface for handler of messages that are added to the internal TDLib log. - */ - public interface LogMessageHandler { - /** - * Callback called on messages that are added to the internal TDLib log. - * - * @param verbosityLevel Log verbosity level with which the message was added from -1 up to 1024. - * If 0, then TDLib will crash as soon as the callback returns. - * None of the TDLib methods can be called from the callback. - * @param message The message added to the internal TDLib log. - */ - void onLogMessage(int verbosityLevel, String message); - } - - /** - * Sends a request to the TDLib. - * - * @param query Object representing a query to the TDLib. - * @param resultHandler Result handler with onResult method which will be called with result - * of the query or with TdApi.Error as parameter. If it is null, nothing - * will be called. - * @param exceptionHandler Exception handler with onException method which will be called on - * exception thrown from resultHandler. If it is null, then - * defaultExceptionHandler will be called. - * @throws NullPointerException if query is null. - */ - public void send(TdApi.Function query, ResultHandler resultHandler, ExceptionHandler exceptionHandler) { - long queryId = currentQueryId.incrementAndGet(); - if (resultHandler != null) { - handlers.put(queryId, new Handler(resultHandler, exceptionHandler)); - } - nativeClientSend(nativeClientId, queryId, query); - } - - /** - * Sends a request to the TDLib with an empty ExceptionHandler. - * - * @param query Object representing a query to the TDLib. - * @param resultHandler Result handler with onResult method which will be called with result - * of the query or with TdApi.Error as parameter. If it is null, then - * defaultExceptionHandler will be called. - * @throws NullPointerException if query is null. - */ - public void send(TdApi.Function query, ResultHandler resultHandler) { - send(query, resultHandler, null); - } - - /** - * Synchronously executes a TDLib request. Only a few marked accordingly requests can be executed synchronously. - * - * @param query Object representing a query to the TDLib. - * @return request result. - * @throws NullPointerException if query is null. - */ - public static TdApi.Object execute(TdApi.Function query) { - return nativeClientExecute(query); - } - - /** - * Creates new Client. - * - * @param updateHandler Handler for incoming updates. - * @param updateExceptionHandler Handler for exceptions thrown from updateHandler. If it is null, exceptions will be iggnored. - * @param defaultExceptionHandler Default handler for exceptions thrown from all ResultHandler. If it is null, exceptions will be iggnored. - * @return created Client - */ - public static Client create(ResultHandler updateHandler, ExceptionHandler updateExceptionHandler, ExceptionHandler defaultExceptionHandler) { - Client client = new Client(updateHandler, updateExceptionHandler, defaultExceptionHandler); - synchronized (responseReceiver) { - if (!responseReceiver.isRun) { - responseReceiver.isRun = true; - - Thread receiverThread = new Thread(responseReceiver, "TDLib thread"); - receiverThread.setDaemon(true); - receiverThread.start(); - } - } - return client; - } - - /** - * Sets the handler for messages that are added to the internal TDLib log. - * None of the TDLib methods can be called from the callback. - * - * @param maxVerbosityLevel The maximum verbosity level of messages for which the callback will be called. - * @param logMessageHandler Handler for messages that are added to the internal TDLib log. Pass null to remove the handler. - */ - public static void setLogMessageHandler(int maxVerbosityLevel, Client.LogMessageHandler logMessageHandler) { - nativeClientSetLogMessageHandler(maxVerbosityLevel, logMessageHandler); - } - - private static class ResponseReceiver implements Runnable { - public boolean isRun = false; - - @Override - public void run() { - while (true) { - int resultN = nativeClientReceive(clientIds, eventIds, events, 100000.0 /*seconds*/); - for (int i = 0; i < resultN; i++) { - processResult(clientIds[i], eventIds[i], events[i]); - events[i] = null; - } - } - } - - private void processResult(int clientId, long id, TdApi.Object object) { - boolean isClosed = false; - if (id == 0 && object instanceof TdApi.UpdateAuthorizationState) { - TdApi.AuthorizationState authorizationState = ((TdApi.UpdateAuthorizationState) object).authorizationState; - if (authorizationState instanceof TdApi.AuthorizationStateClosed) { - isClosed = true; - } - } - - Handler handler = id == 0 ? updateHandlers.get(clientId) : handlers.remove(id); - if (handler != null) { - try { - handler.resultHandler.onResult(object); - } catch (Throwable cause) { - ExceptionHandler exceptionHandler = handler.exceptionHandler; - if (exceptionHandler == null) { - exceptionHandler = defaultExceptionHandlers.get(clientId); - } - if (exceptionHandler != null) { - try { - exceptionHandler.onException(cause); - } catch (Throwable ignored) { - } - } - } - } - - if (isClosed) { - updateHandlers.remove(clientId); // there will be no more updates - defaultExceptionHandlers.remove(clientId); // ignore further exceptions - clientCount.decrementAndGet(); - } - } - - private static final int MAX_EVENTS = 1000; - private final int[] clientIds = new int[MAX_EVENTS]; - private final long[] eventIds = new long[MAX_EVENTS]; - private final TdApi.Object[] events = new TdApi.Object[MAX_EVENTS]; - } - - private final int nativeClientId; - - private static final ConcurrentHashMap defaultExceptionHandlers = new ConcurrentHashMap(); - private static final ConcurrentHashMap updateHandlers = new ConcurrentHashMap(); - private static final ConcurrentHashMap handlers = new ConcurrentHashMap(); - private static final AtomicLong currentQueryId = new AtomicLong(); - private static final AtomicLong clientCount = new AtomicLong(); - - private static final ResponseReceiver responseReceiver = new ResponseReceiver(); - - private static class Handler { - final ResultHandler resultHandler; - final ExceptionHandler exceptionHandler; - - Handler(ResultHandler resultHandler, ExceptionHandler exceptionHandler) { - this.resultHandler = resultHandler; - this.exceptionHandler = exceptionHandler; - } - } - - private Client(ResultHandler updateHandler, ExceptionHandler updateExceptionHandler, ExceptionHandler defaultExceptionHandler) { - clientCount.incrementAndGet(); - nativeClientId = createNativeClient(); - if (updateHandler != null) { - updateHandlers.put(nativeClientId, new Handler(updateHandler, updateExceptionHandler)); - } - if (defaultExceptionHandler != null) { - defaultExceptionHandlers.put(nativeClientId, defaultExceptionHandler); - } - send(new TdApi.GetOption("version"), null, null); - } - - @Override - protected void finalize() throws Throwable { - send(new TdApi.Close(), null, null); - } - - private static native int createNativeClient(); - - private static native void nativeClientSend(int nativeClientId, long eventId, TdApi.Function function); - - private static native int nativeClientReceive(int[] clientIds, long[] eventIds, TdApi.Object[] events, double timeout); - - private static native TdApi.Object nativeClientExecute(TdApi.Function function); - - private static native void nativeClientSetLogMessageHandler(int maxVerbosityLevel, LogMessageHandler logMessageHandler); -} diff --git a/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java b/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java deleted file mode 100644 index 7e76b42276..0000000000 --- a/protocols/Telegram/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java +++ /dev/null @@ -1,685 +0,0 @@ -// -// 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) -// -package org.drinkless.tdlib.example; - -import org.drinkless.tdlib.Client; -import org.drinkless.tdlib.TdApi; - -import java.io.BufferedReader; -import java.io.IOError; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.NavigableSet; -import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -/** - * Example class for TDLib usage from Java. - */ -public final class Example { - private static Client client = null; - - private static TdApi.AuthorizationState authorizationState = null; - private static volatile boolean haveAuthorization = false; - private static volatile boolean needQuit = false; - private static volatile boolean canQuit = false; - - private static final Client.ResultHandler defaultHandler = new DefaultHandler(); - - private static final Lock authorizationLock = new ReentrantLock(); - private static final Condition gotAuthorization = authorizationLock.newCondition(); - - private static final ConcurrentMap users = new ConcurrentHashMap(); - private static final ConcurrentMap basicGroups = new ConcurrentHashMap(); - private static final ConcurrentMap supergroups = new ConcurrentHashMap(); - private static final ConcurrentMap secretChats = new ConcurrentHashMap(); - - private static final ConcurrentMap chats = new ConcurrentHashMap(); - private static final NavigableSet mainChatList = new TreeSet(); - private static boolean haveFullMainChatList = false; - - private static final ConcurrentMap usersFullInfo = new ConcurrentHashMap(); - private static final ConcurrentMap basicGroupsFullInfo = new ConcurrentHashMap(); - private static final ConcurrentMap supergroupsFullInfo = new ConcurrentHashMap(); - - private static final String newLine = System.getProperty("line.separator"); - private static final String commandsLine = "Enter command (gcs - GetChats, gc - GetChat, me - GetMe, sm - SendMessage, lo - LogOut, q - Quit): "; - private static volatile String currentPrompt = null; - - private static void print(String str) { - if (currentPrompt != null) { - System.out.println(""); - } - System.out.println(str); - if (currentPrompt != null) { - System.out.print(currentPrompt); - } - } - - private static void setChatPositions(TdApi.Chat chat, TdApi.ChatPosition[] positions) { - synchronized (mainChatList) { - synchronized (chat) { - for (TdApi.ChatPosition position : chat.positions) { - if (position.list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) { - boolean isRemoved = mainChatList.remove(new OrderedChat(chat.id, position)); - assert isRemoved; - } - } - - chat.positions = positions; - - for (TdApi.ChatPosition position : chat.positions) { - if (position.list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) { - boolean isAdded = mainChatList.add(new OrderedChat(chat.id, position)); - assert isAdded; - } - } - } - } - } - - private static void onAuthorizationStateUpdated(TdApi.AuthorizationState authorizationState) { - if (authorizationState != null) { - Example.authorizationState = authorizationState; - } - switch (Example.authorizationState.getConstructor()) { - case TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR: - TdApi.SetTdlibParameters request = new TdApi.SetTdlibParameters(); - request.databaseDirectory = "tdlib"; - request.useMessageDatabase = true; - request.useSecretChats = true; - request.apiId = 94575; - request.apiHash = "a3406de8d171bb422bb6ddf3bbd800e2"; - request.systemLanguageCode = "en"; - request.deviceModel = "Desktop"; - request.applicationVersion = "1.0"; - request.enableStorageOptimizer = true; - - client.send(request, new AuthorizationRequestHandler()); - break; - case TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR: { - String phoneNumber = promptString("Please enter phone number: "); - client.send(new TdApi.SetAuthenticationPhoneNumber(phoneNumber, null), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateWaitOtherDeviceConfirmation.CONSTRUCTOR: { - String link = ((TdApi.AuthorizationStateWaitOtherDeviceConfirmation) Example.authorizationState).link; - System.out.println("Please confirm this login link on another device: " + link); - break; - } - case TdApi.AuthorizationStateWaitEmailAddress.CONSTRUCTOR: { - String emailAddress = promptString("Please enter email address: "); - client.send(new TdApi.SetAuthenticationEmailAddress(emailAddress), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateWaitEmailCode.CONSTRUCTOR: { - String code = promptString("Please enter email authentication code: "); - client.send(new TdApi.CheckAuthenticationEmailCode(new TdApi.EmailAddressAuthenticationCode(code)), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateWaitCode.CONSTRUCTOR: { - String code = promptString("Please enter authentication code: "); - client.send(new TdApi.CheckAuthenticationCode(code), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateWaitRegistration.CONSTRUCTOR: { - String firstName = promptString("Please enter your first name: "); - String lastName = promptString("Please enter your last name: "); - client.send(new TdApi.RegisterUser(firstName, lastName), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR: { - String password = promptString("Please enter password: "); - client.send(new TdApi.CheckAuthenticationPassword(password), new AuthorizationRequestHandler()); - break; - } - case TdApi.AuthorizationStateReady.CONSTRUCTOR: - haveAuthorization = true; - authorizationLock.lock(); - try { - gotAuthorization.signal(); - } finally { - authorizationLock.unlock(); - } - break; - case TdApi.AuthorizationStateLoggingOut.CONSTRUCTOR: - haveAuthorization = false; - print("Logging out"); - break; - case TdApi.AuthorizationStateClosing.CONSTRUCTOR: - haveAuthorization = false; - print("Closing"); - break; - case TdApi.AuthorizationStateClosed.CONSTRUCTOR: - print("Closed"); - if (!needQuit) { - client = Client.create(new UpdateHandler(), null, null); // recreate client after previous has closed - } else { - canQuit = true; - } - break; - default: - System.err.println("Unsupported authorization state:" + newLine + Example.authorizationState); - } - } - - private static int toInt(String arg) { - int result = 0; - try { - result = Integer.parseInt(arg); - } catch (NumberFormatException ignored) { - } - return result; - } - - private static long getChatId(String arg) { - long chatId = 0; - try { - chatId = Long.parseLong(arg); - } catch (NumberFormatException ignored) { - } - return chatId; - } - - private static String promptString(String prompt) { - System.out.print(prompt); - currentPrompt = prompt; - BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - String str = ""; - try { - str = reader.readLine(); - } catch (IOException e) { - e.printStackTrace(); - } - currentPrompt = null; - return str; - } - - private static void getCommand() { - String command = promptString(commandsLine); - String[] commands = command.split(" ", 2); - try { - switch (commands[0]) { - case "gcs": { - int limit = 20; - if (commands.length > 1) { - limit = toInt(commands[1]); - } - getMainChatList(limit); - break; - } - case "gc": - client.send(new TdApi.GetChat(getChatId(commands[1])), defaultHandler); - break; - case "me": - client.send(new TdApi.GetMe(), defaultHandler); - break; - case "sm": { - String[] args = commands[1].split(" ", 2); - sendMessage(getChatId(args[0]), args[1]); - break; - } - case "lo": - haveAuthorization = false; - client.send(new TdApi.LogOut(), defaultHandler); - break; - case "q": - needQuit = true; - haveAuthorization = false; - client.send(new TdApi.Close(), defaultHandler); - break; - default: - System.err.println("Unsupported command: " + command); - } - } catch (ArrayIndexOutOfBoundsException e) { - print("Not enough arguments"); - } - } - - private static void getMainChatList(final int limit) { - synchronized (mainChatList) { - if (!haveFullMainChatList && limit > mainChatList.size()) { - // send LoadChats request if there are some unknown chats and have not enough known chats - client.send(new TdApi.LoadChats(new TdApi.ChatListMain(), limit - mainChatList.size()), new Client.ResultHandler() { - @Override - public void onResult(TdApi.Object object) { - switch (object.getConstructor()) { - case TdApi.Error.CONSTRUCTOR: - if (((TdApi.Error) object).code == 404) { - synchronized (mainChatList) { - haveFullMainChatList = true; - } - } else { - System.err.println("Receive an error for LoadChats:" + newLine + object); - } - break; - case TdApi.Ok.CONSTRUCTOR: - // chats had already been received through updates, let's retry request - getMainChatList(limit); - break; - default: - System.err.println("Receive wrong response from TDLib:" + newLine + object); - } - } - }); - return; - } - - java.util.Iterator iter = mainChatList.iterator(); - System.out.println(); - System.out.println("First " + limit + " chat(s) out of " + mainChatList.size() + " known chat(s):"); - for (int i = 0; i < limit && i < mainChatList.size(); i++) { - long chatId = iter.next().chatId; - TdApi.Chat chat = chats.get(chatId); - synchronized (chat) { - System.out.println(chatId + ": " + chat.title); - } - } - print(""); - } - } - - private static void sendMessage(long chatId, String message) { - // initialize reply markup just for testing - TdApi.InlineKeyboardButton[] row = {new TdApi.InlineKeyboardButton("https://telegram.org?1", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?2", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?3", new TdApi.InlineKeyboardButtonTypeUrl())}; - TdApi.ReplyMarkup replyMarkup = new TdApi.ReplyMarkupInlineKeyboard(new TdApi.InlineKeyboardButton[][]{row, row, row}); - - TdApi.InputMessageContent content = new TdApi.InputMessageText(new TdApi.FormattedText(message, null), false, true); - client.send(new TdApi.SendMessage(chatId, 0, 0, null, replyMarkup, content), defaultHandler); - } - - public static void main(String[] args) throws InterruptedException { - // set log message handler to handle only fatal errors (0) and plain log messages (-1) - Client.setLogMessageHandler(0, new LogMessageHandler()); - - // disable TDLib log and redirect fatal errors and plain log messages to a file - Client.execute(new TdApi.SetLogVerbosityLevel(0)); - if (Client.execute(new TdApi.SetLogStream(new TdApi.LogStreamFile("tdlib.log", 1 << 27, false))) instanceof TdApi.Error) { - throw new IOError(new IOException("Write access to the current directory is required")); - } - - // create client - client = Client.create(new UpdateHandler(), null, null); - - // test Client.execute - defaultHandler.onResult(Client.execute(new TdApi.GetTextEntities("@telegram /test_command https://telegram.org telegram.me @gif @test"))); - - // main loop - while (!needQuit) { - // await authorization - authorizationLock.lock(); - try { - while (!haveAuthorization) { - gotAuthorization.await(); - } - } finally { - authorizationLock.unlock(); - } - - while (haveAuthorization) { - getCommand(); - } - } - while (!canQuit) { - Thread.sleep(1); - } - } - - private static class OrderedChat implements Comparable { - final long chatId; - final TdApi.ChatPosition position; - - OrderedChat(long chatId, TdApi.ChatPosition position) { - this.chatId = chatId; - this.position = position; - } - - @Override - public int compareTo(OrderedChat o) { - if (this.position.order != o.position.order) { - return o.position.order < this.position.order ? -1 : 1; - } - if (this.chatId != o.chatId) { - return o.chatId < this.chatId ? -1 : 1; - } - return 0; - } - - @Override - public boolean equals(Object obj) { - OrderedChat o = (OrderedChat) obj; - return this.chatId == o.chatId && this.position.order == o.position.order; - } - } - - private static class DefaultHandler implements Client.ResultHandler { - @Override - public void onResult(TdApi.Object object) { - print(object.toString()); - } - } - - private static class UpdateHandler implements Client.ResultHandler { - @Override - public void onResult(TdApi.Object object) { - switch (object.getConstructor()) { - case TdApi.UpdateAuthorizationState.CONSTRUCTOR: - onAuthorizationStateUpdated(((TdApi.UpdateAuthorizationState) object).authorizationState); - break; - - case TdApi.UpdateUser.CONSTRUCTOR: - TdApi.UpdateUser updateUser = (TdApi.UpdateUser) object; - users.put(updateUser.user.id, updateUser.user); - break; - case TdApi.UpdateUserStatus.CONSTRUCTOR: { - TdApi.UpdateUserStatus updateUserStatus = (TdApi.UpdateUserStatus) object; - TdApi.User user = users.get(updateUserStatus.userId); - synchronized (user) { - user.status = updateUserStatus.status; - } - break; - } - case TdApi.UpdateBasicGroup.CONSTRUCTOR: - TdApi.UpdateBasicGroup updateBasicGroup = (TdApi.UpdateBasicGroup) object; - basicGroups.put(updateBasicGroup.basicGroup.id, updateBasicGroup.basicGroup); - break; - case TdApi.UpdateSupergroup.CONSTRUCTOR: - TdApi.UpdateSupergroup updateSupergroup = (TdApi.UpdateSupergroup) object; - supergroups.put(updateSupergroup.supergroup.id, updateSupergroup.supergroup); - break; - case TdApi.UpdateSecretChat.CONSTRUCTOR: - TdApi.UpdateSecretChat updateSecretChat = (TdApi.UpdateSecretChat) object; - secretChats.put(updateSecretChat.secretChat.id, updateSecretChat.secretChat); - break; - - case TdApi.UpdateNewChat.CONSTRUCTOR: { - TdApi.UpdateNewChat updateNewChat = (TdApi.UpdateNewChat) object; - TdApi.Chat chat = updateNewChat.chat; - synchronized (chat) { - chats.put(chat.id, chat); - - TdApi.ChatPosition[] positions = chat.positions; - chat.positions = new TdApi.ChatPosition[0]; - setChatPositions(chat, positions); - } - break; - } - case TdApi.UpdateChatTitle.CONSTRUCTOR: { - TdApi.UpdateChatTitle updateChat = (TdApi.UpdateChatTitle) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.title = updateChat.title; - } - break; - } - case TdApi.UpdateChatPhoto.CONSTRUCTOR: { - TdApi.UpdateChatPhoto updateChat = (TdApi.UpdateChatPhoto) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.photo = updateChat.photo; - } - break; - } - case TdApi.UpdateChatLastMessage.CONSTRUCTOR: { - TdApi.UpdateChatLastMessage updateChat = (TdApi.UpdateChatLastMessage) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.lastMessage = updateChat.lastMessage; - setChatPositions(chat, updateChat.positions); - } - break; - } - case TdApi.UpdateChatPosition.CONSTRUCTOR: { - TdApi.UpdateChatPosition updateChat = (TdApi.UpdateChatPosition) object; - if (updateChat.position.list.getConstructor() != TdApi.ChatListMain.CONSTRUCTOR) { - break; - } - - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - int i; - for (i = 0; i < chat.positions.length; i++) { - if (chat.positions[i].list.getConstructor() == TdApi.ChatListMain.CONSTRUCTOR) { - break; - } - } - TdApi.ChatPosition[] new_positions = new TdApi.ChatPosition[chat.positions.length + (updateChat.position.order == 0 ? 0 : 1) - (i < chat.positions.length ? 1 : 0)]; - int pos = 0; - if (updateChat.position.order != 0) { - new_positions[pos++] = updateChat.position; - } - for (int j = 0; j < chat.positions.length; j++) { - if (j != i) { - new_positions[pos++] = chat.positions[j]; - } - } - assert pos == new_positions.length; - - setChatPositions(chat, new_positions); - } - break; - } - case TdApi.UpdateChatReadInbox.CONSTRUCTOR: { - TdApi.UpdateChatReadInbox updateChat = (TdApi.UpdateChatReadInbox) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.lastReadInboxMessageId = updateChat.lastReadInboxMessageId; - chat.unreadCount = updateChat.unreadCount; - } - break; - } - case TdApi.UpdateChatReadOutbox.CONSTRUCTOR: { - TdApi.UpdateChatReadOutbox updateChat = (TdApi.UpdateChatReadOutbox) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.lastReadOutboxMessageId = updateChat.lastReadOutboxMessageId; - } - break; - } - case TdApi.UpdateChatUnreadMentionCount.CONSTRUCTOR: { - TdApi.UpdateChatUnreadMentionCount updateChat = (TdApi.UpdateChatUnreadMentionCount) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.unreadMentionCount = updateChat.unreadMentionCount; - } - break; - } - case TdApi.UpdateMessageMentionRead.CONSTRUCTOR: { - TdApi.UpdateMessageMentionRead updateChat = (TdApi.UpdateMessageMentionRead) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.unreadMentionCount = updateChat.unreadMentionCount; - } - break; - } - case TdApi.UpdateChatReplyMarkup.CONSTRUCTOR: { - TdApi.UpdateChatReplyMarkup updateChat = (TdApi.UpdateChatReplyMarkup) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.replyMarkupMessageId = updateChat.replyMarkupMessageId; - } - break; - } - case TdApi.UpdateChatDraftMessage.CONSTRUCTOR: { - TdApi.UpdateChatDraftMessage updateChat = (TdApi.UpdateChatDraftMessage) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.draftMessage = updateChat.draftMessage; - setChatPositions(chat, updateChat.positions); - } - break; - } - case TdApi.UpdateChatPermissions.CONSTRUCTOR: { - TdApi.UpdateChatPermissions update = (TdApi.UpdateChatPermissions) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.permissions = update.permissions; - } - break; - } - case TdApi.UpdateChatNotificationSettings.CONSTRUCTOR: { - TdApi.UpdateChatNotificationSettings update = (TdApi.UpdateChatNotificationSettings) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.notificationSettings = update.notificationSettings; - } - break; - } - case TdApi.UpdateChatDefaultDisableNotification.CONSTRUCTOR: { - TdApi.UpdateChatDefaultDisableNotification update = (TdApi.UpdateChatDefaultDisableNotification) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.defaultDisableNotification = update.defaultDisableNotification; - } - break; - } - case TdApi.UpdateChatIsMarkedAsUnread.CONSTRUCTOR: { - TdApi.UpdateChatIsMarkedAsUnread update = (TdApi.UpdateChatIsMarkedAsUnread) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.isMarkedAsUnread = update.isMarkedAsUnread; - } - break; - } - case TdApi.UpdateChatIsBlocked.CONSTRUCTOR: { - TdApi.UpdateChatIsBlocked update = (TdApi.UpdateChatIsBlocked) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.isBlocked = update.isBlocked; - } - break; - } - case TdApi.UpdateChatHasScheduledMessages.CONSTRUCTOR: { - TdApi.UpdateChatHasScheduledMessages update = (TdApi.UpdateChatHasScheduledMessages) object; - TdApi.Chat chat = chats.get(update.chatId); - synchronized (chat) { - chat.hasScheduledMessages = update.hasScheduledMessages; - } - break; - } - - case TdApi.UpdateUserFullInfo.CONSTRUCTOR: - TdApi.UpdateUserFullInfo updateUserFullInfo = (TdApi.UpdateUserFullInfo) object; - usersFullInfo.put(updateUserFullInfo.userId, updateUserFullInfo.userFullInfo); - break; - case TdApi.UpdateBasicGroupFullInfo.CONSTRUCTOR: - TdApi.UpdateBasicGroupFullInfo updateBasicGroupFullInfo = (TdApi.UpdateBasicGroupFullInfo) object; - basicGroupsFullInfo.put(updateBasicGroupFullInfo.basicGroupId, updateBasicGroupFullInfo.basicGroupFullInfo); - break; - case TdApi.UpdateSupergroupFullInfo.CONSTRUCTOR: - TdApi.UpdateSupergroupFullInfo updateSupergroupFullInfo = (TdApi.UpdateSupergroupFullInfo) object; - supergroupsFullInfo.put(updateSupergroupFullInfo.supergroupId, updateSupergroupFullInfo.supergroupFullInfo); - break; - default: - // print("Unsupported update:" + newLine + object); - } - } - } - - private static class AuthorizationRequestHandler implements Client.ResultHandler { - @Override - public void onResult(TdApi.Object object) { - switch (object.getConstructor()) { - case TdApi.Error.CONSTRUCTOR: - System.err.println("Receive an error:" + newLine + object); - onAuthorizationStateUpdated(null); // repeat last action - break; - case TdApi.Ok.CONSTRUCTOR: - // result is already received through UpdateAuthorizationState, nothing to do - break; - default: - System.err.println("Receive wrong response from TDLib:" + newLine + object); - } - } - } - - private static class LogMessageHandler implements Client.LogMessageHandler { - @Override - public void onLogMessage(int verbosityLevel, String message) { - if (verbosityLevel == 0) { - onFatalError(message); - return; - } - System.err.println(message); - } - } - - private static void onFatalError(String errorMessage) { - final class ThrowError implements Runnable { - private final String errorMessage; - private final AtomicLong errorThrowTime; - - private ThrowError(String errorMessage, AtomicLong errorThrowTime) { - this.errorMessage = errorMessage; - this.errorThrowTime = errorThrowTime; - } - - @Override - public void run() { - if (isDatabaseBrokenError(errorMessage) || isDiskFullError(errorMessage) || isDiskError(errorMessage)) { - processExternalError(); - return; - } - - errorThrowTime.set(System.currentTimeMillis()); - throw new ClientError("TDLib fatal error: " + errorMessage); - } - - private void processExternalError() { - errorThrowTime.set(System.currentTimeMillis()); - throw new ExternalClientError("Fatal error: " + errorMessage); - } - - final class ClientError extends Error { - private ClientError(String message) { - super(message); - } - } - - final class ExternalClientError extends Error { - public ExternalClientError(String message) { - super(message); - } - } - - private boolean isDatabaseBrokenError(String message) { - return message.contains("Wrong key or database is corrupted") || - message.contains("SQL logic error or missing database") || - message.contains("database disk image is malformed") || - message.contains("file is encrypted or is not a database") || - message.contains("unsupported file format") || - message.contains("Database was corrupted and deleted during execution and can't be recreated"); - } - - private boolean isDiskFullError(String message) { - return message.contains("PosixError : No space left on device") || - message.contains("database or disk is full"); - } - - private boolean isDiskError(String message) { - return message.contains("I/O error") || message.contains("Structure needs cleaning"); - } - } - - final AtomicLong errorThrowTime = new AtomicLong(Long.MAX_VALUE); - new Thread(new ThrowError(errorMessage, errorThrowTime), "TDLib fatal error thread").start(); - - // wait at least 10 seconds after the error is thrown - while (errorThrowTime.get() >= System.currentTimeMillis() - 10000) { - try { - Thread.sleep(1000 /* milliseconds */); - } catch (InterruptedException ignore) { - Thread.currentThread().interrupt(); - } - } - } -} diff --git a/protocols/Telegram/tdlib/td/example/java/td_jni.cpp b/protocols/Telegram/tdlib/td/example/java/td_jni.cpp deleted file mode 100644 index 15c60a9545..0000000000 --- a/protocols/Telegram/tdlib/td/example/java/td_jni.cpp +++ /dev/null @@ -1,182 +0,0 @@ -// -// 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 -#include - -#include - -#include -#include -#include -#include - -namespace td_jni { - -static td::td_api::object_ptr fetch_function(JNIEnv *env, jobject function) { - td::jni::reset_parse_error(); - auto result = td::td_api::Function::fetch(env, function); - if (td::jni::have_parse_error()) { - std::abort(); - } - return result; -} - -static td::ClientManager *get_manager() { - return td::ClientManager::get_manager_singleton(); -} - -static jint Client_createNativeClient(JNIEnv *env, jclass clazz) { - return static_cast(get_manager()->create_client_id()); -} - -static void Client_nativeClientSend(JNIEnv *env, jclass clazz, jint client_id, jlong id, jobject function) { - get_manager()->send(static_cast(client_id), static_cast(id), - fetch_function(env, function)); -} - -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 *manager = get_manager(); - auto response = manager->receive(timeout); - while (response.object) { - auto client_id = static_cast(response.client_id); - env->SetIntArrayRegion(client_ids, result_size, 1, &client_id); - - auto request_id = static_cast(response.request_id); - env->SetLongArrayRegion(ids, result_size, 1, &request_id); - - jobject object; - response.object->store(env, object); - env->SetObjectArrayElement(events, result_size, object); - env->DeleteLocalRef(object); - - result_size++; - 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::ClientManager::execute(fetch_function(env, function))->store(env, result); - return result; -} - -static jstring Object_toString(JNIEnv *env, jobject object) { - return td::jni::to_jstring(env, to_string(td::td_api::Object::fetch(env, object))); -} - -static jstring Function_toString(JNIEnv *env, jobject object) { - return td::jni::to_jstring(env, to_string(td::td_api::Function::fetch(env, object))); -} - -static constexpr jint JAVA_VERSION = JNI_VERSION_1_6; -static JavaVM *java_vm; -static jobject log_message_handler; - -static void on_log_message(int verbosity_level, const char *log_message) { - auto env = td::jni::get_jni_env(java_vm, JAVA_VERSION); - 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(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(max_verbosity_level), on_log_message); - } -} - -static jint register_native(JavaVM *vm) { - JNIEnv *env; - if (vm->GetEnv(reinterpret_cast(&env), JAVA_VERSION) != JNI_OK) { - return -1; - } - - java_vm = vm; - - auto register_method = [env](jclass clazz, std::string name, std::string signature, auto function_ptr) { - td::jni::register_native_method(env, clazz, std::move(name), std::move(signature), - reinterpret_cast(function_ptr)); - }; - - auto client_class = td::jni::get_jclass(env, PACKAGE_NAME "/Client"); - 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", "()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, "nativeClientSetLogMessageHandler", "(IL" PACKAGE_NAME "/Client$LogMessageHandler;)V", - Client_nativeClientSetLogMessageHandler); - - register_method(object_class, "toString", "()Ljava/lang/String;", Object_toString); - - register_method(function_class, "toString", "()Ljava/lang/String;", Function_toString); -#undef TD_FUNCTION -#undef TD_OBJECT - - 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); - - return JAVA_VERSION; -} - -} // namespace td_jni - -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { - static jint jni_version = td_jni::register_native(vm); // call_once - return jni_version; -} -- cgit v1.2.3