diff options
author | aunsane <aunsane@gmail.com> | 2018-04-27 21:33:17 +0300 |
---|---|---|
committer | aunsane <aunsane@gmail.com> | 2018-04-27 21:33:17 +0300 |
commit | e1ec72eab6d00b3ba38e5932bc88920f103b6e4a (patch) | |
tree | 999de2725a83e30fbbf6576200525d4ef0c5fe38 /libs/tdlib/td/example/java | |
parent | b9ce1d4d98525490ca1a38e2d9fd4f3369adb3e0 (diff) |
Telegram: initial commit
- tdlib moved to telegram dir
Diffstat (limited to 'libs/tdlib/td/example/java')
-rw-r--r-- | libs/tdlib/td/example/java/.gitignore | 5 | ||||
-rw-r--r-- | libs/tdlib/td/example/java/CMakeLists.txt | 68 | ||||
-rw-r--r-- | libs/tdlib/td/example/java/README.md | 39 | ||||
-rw-r--r-- | libs/tdlib/td/example/java/org/drinkless/tdlib/Client.java | 285 | ||||
-rw-r--r-- | libs/tdlib/td/example/java/org/drinkless/tdlib/Log.java | 75 | ||||
-rw-r--r-- | libs/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java | 533 | ||||
-rw-r--r-- | libs/tdlib/td/example/java/td_jni.cpp | 158 |
7 files changed, 0 insertions, 1163 deletions
diff --git a/libs/tdlib/td/example/java/.gitignore b/libs/tdlib/td/example/java/.gitignore deleted file mode 100644 index 8f846b80d9..0000000000 --- a/libs/tdlib/td/example/java/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -**/*build/ -bin/ -docs/ -org/drinkless/tdlib/TdApi.java -td/ diff --git a/libs/tdlib/td/example/java/CMakeLists.txt b/libs/tdlib/td/example/java/CMakeLists.txt deleted file mode 100644 index e8313a68b7..0000000000 --- a/libs/tdlib/td/example/java/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ -cmake_minimum_required(VERSION 3.1 FATAL_ERROR) - -project(TdJavaExample VERSION 1.0 LANGUAGES CXX) - -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 1.6 REQUIRED) -endif() -message(STATUS "Found Java: ${Java_JAVAC_EXECUTABLE} ${Java_JAVADOC_EXECUTABLE}") - -# Generating TdApi.java -find_program(PHP_EXECUTABLE php) - -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} -d ${JAVA_OUTPUT_DIRECTORY} ${JAVA_SOURCE_PATH}/example/Example.java ${JAVA_SOURCE_PATH}/Client.java ${JAVA_SOURCE_PATH}/Log.java ${JAVA_SOURCE_PATH}/TdApi.java - COMMENT "Building Java code" - DEPENDS td_generate_java_api -) - -set(JAVA_SOURCE_PATH "${TD_API_JAVA_PATH}/${TD_API_JAVA_PACKAGE}") -add_custom_target(generate_javadoc - COMMAND ${Java_JAVADOC_EXECUTABLE} -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}") - -set_property(TARGET tdjni PROPERTY CXX_STANDARD 14) - -add_dependencies(tdjni td_generate_java_api build_java generate_javadoc) - -install(TARGETS tdjni - LIBRARY DESTINATION bin - RUNTIME DESTINATION bin -) diff --git a/libs/tdlib/td/example/java/README.md b/libs/tdlib/td/example/java/README.md deleted file mode 100644 index c2b5c43171..0000000000 --- a/libs/tdlib/td/example/java/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# TDLib Java example - -To run this example, you will need installed JDK >= 1.6. -For Javadoc documentation generation PHP is needed. - -TDLib should be prebuilt for using with Java and installed to local subdirectory `td/` as follows: -``` -cd <path to TDLib sources> -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 64-bit Java on Windows using MSVC, you will also need to add `-A x64` option to CMake. - -In Windows, use Vcpkg toolchain file by adding parameter -DCMAKE_TOOLCHAIN_FILE=<VCPKG_DIR>/scripts/buildsystems/vcpkg.cmake - -Then you can build this example: -``` -cd <path to TDLib sources>/example/java -mkdir build -cd build -cmake -DCMAKE_BUILD_TYPE=Release -DTd_DIR=<full path to TDLib sources>/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 <path to TDLib sources>/example/java/bin -java '-Djava.library.path=.' org/drinkless/tdlib/example/Example -``` - -If you get "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 get java.lang.UnsatisfiedLinkError with "Can't find dependent libraries", you may also need to copy some dependent shared libraries to `bin/`. - -In case you compiled the example as 32-bit version, you may need to give -d32 parameter to Java. diff --git a/libs/tdlib/td/example/java/org/drinkless/tdlib/Client.java b/libs/tdlib/td/example/java/org/drinkless/tdlib/Client.java deleted file mode 100644 index efb38e9c5a..0000000000 --- a/libs/tdlib/td/example/java/org/drinkless/tdlib/Client.java +++ /dev/null @@ -1,285 +0,0 @@ -// -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 -// -// 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; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * Main class for interaction with the TDLib. - */ -public final class Client implements Runnable { - /** - * 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); - } - - /** - * 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) { - if (query == null) { - throw new NullPointerException("query is null"); - } - - readLock.lock(); - try { - if (isClientDestroyed) { - if (resultHandler != null) { - handleResult(new TdApi.Error(500, "Client is closed"), resultHandler, exceptionHandler); - } - return; - } - - long queryId = currentQueryId.incrementAndGet(); - handlers.put(queryId, new Handler(resultHandler, exceptionHandler)); - nativeClientSend(nativeClientId, queryId, query); - } finally { - readLock.unlock(); - } - } - - /** - * 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) { - if (query == null) { - throw new NullPointerException("query is null"); - } - return nativeClientExecute(query); - } - - /** - * Replaces handler for incoming updates from the TDLib. - * - * @param updatesHandler Handler with onResult method which will be called for every incoming - * update from the TDLib. - * @param exceptionHandler Exception handler with onException method which will be called on - * exception thrown from updatesHandler, if it is null, defaultExceptionHandler will be invoked. - */ - public void setUpdatesHandler(ResultHandler updatesHandler, ExceptionHandler exceptionHandler) { - handlers.put(0L, new Handler(updatesHandler, exceptionHandler)); - } - - /** - * Replaces handler for incoming updates from the TDLib. Sets empty ExceptionHandler. - * - * @param updatesHandler Handler with onResult method which will be called for every incoming - * update from the TDLib. - */ - public void setUpdatesHandler(ResultHandler updatesHandler) { - setUpdatesHandler(updatesHandler, null); - } - - /** - * Replaces default exception handler to be invoked on exceptions thrown from updatesHandler and all other ResultHandler. - * - * @param defaultExceptionHandler Default exception handler. If null Exceptions are ignored. - */ - public void setDefaultExceptionHandler(Client.ExceptionHandler defaultExceptionHandler) { - this.defaultExceptionHandler = defaultExceptionHandler; - } - - /** - * Overridden method from Runnable, do not call it directly. - */ - @Override - public void run() { - while (!stopFlag) { - receiveQueries(300.0 /*seconds*/); - } - } - - /** - * Creates new Client. - * - * @param updatesHandler Handler for incoming updates. - * @param updatesExceptionHandler Handler for exceptions thrown from updatesHandler. 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 updatesHandler, ExceptionHandler updatesExceptionHandler, ExceptionHandler defaultExceptionHandler) { - Client client = new Client(updatesHandler, updatesExceptionHandler, defaultExceptionHandler); - new Thread(client, "TDLib thread").start(); - return client; - } - - /** - * Closes Client. - */ - public void close() { - writeLock.lock(); - try { - if (isClientDestroyed) { - return; - } - if (!stopFlag) { - send(new TdApi.Close(), null); - } - isClientDestroyed = true; - while (!stopFlag) { - Thread.yield(); - } - while (handlers.size() != 1) { - receiveQueries(300.0); - } - destroyNativeClient(nativeClientId); - } finally { - writeLock.unlock(); - } - } - - private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); - private final Lock readLock = readWriteLock.readLock(); - private final Lock writeLock = readWriteLock.writeLock(); - - private volatile boolean stopFlag = false; - private volatile boolean isClientDestroyed = false; - private final long nativeClientId; - - private final ConcurrentHashMap<Long, Handler> handlers = new ConcurrentHashMap<Long, Handler>(); - private final AtomicLong currentQueryId = new AtomicLong(); - - private volatile ExceptionHandler defaultExceptionHandler = null; - - private static final int MAX_EVENTS = 1000; - private final long[] eventIds = new long[MAX_EVENTS]; - private final TdApi.Object[] events = new TdApi.Object[MAX_EVENTS]; - - private static class Handler { - final ResultHandler resultHandler; - final ExceptionHandler exceptionHandler; - - Handler(ResultHandler resultHandler, ExceptionHandler exceptionHandler) { - this.resultHandler = resultHandler; - this.exceptionHandler = exceptionHandler; - } - } - - private Client(ResultHandler updatesHandler, ExceptionHandler updateExceptionHandler, ExceptionHandler defaultExceptionHandler) { - nativeClientId = createNativeClient(); - handlers.put(0L, new Handler(updatesHandler, updateExceptionHandler)); - this.defaultExceptionHandler = defaultExceptionHandler; - } - - @Override - protected void finalize() throws Throwable { - try { - close(); - } finally { - super.finalize(); - } - } - - private void processResult(long id, TdApi.Object object) { - if (object instanceof TdApi.UpdateAuthorizationState) { - if (((TdApi.UpdateAuthorizationState) object).authorizationState instanceof TdApi.AuthorizationStateClosed) { - stopFlag = true; - } - } - Handler handler; - if (id == 0) { - // update handler stays forever - handler = handlers.get(id); - } else { - handler = handlers.remove(id); - } - if (handler == null) { - return; - } - - handleResult(object, handler.resultHandler, handler.exceptionHandler); - } - - private void handleResult(TdApi.Object object, ResultHandler resultHandler, ExceptionHandler exceptionHandler) { - if (resultHandler == null) { - return; - } - - try { - resultHandler.onResult(object); - } catch (Throwable cause) { - if (exceptionHandler == null) { - exceptionHandler = defaultExceptionHandler; - } - if (exceptionHandler != null) { - try { - exceptionHandler.onException(cause); - } catch (Throwable ignored) { - } - } - } - } - - private void receiveQueries(double timeout) { - int resultN = nativeClientReceive(nativeClientId, eventIds, events, timeout); - for (int i = 0; i < resultN; i++) { - processResult(eventIds[i], events[i]); - events[i] = null; - } - } - - private static native long createNativeClient(); - - private static native void nativeClientSend(long nativeClientId, long eventId, TdApi.Function function); - - private static native int nativeClientReceive(long nativeClientId, long[] eventIds, TdApi.Object[] events, double timeout); - - private static native TdApi.Object nativeClientExecute(TdApi.Function function); - - private static native void destroyNativeClient(long nativeClientId); -} diff --git a/libs/tdlib/td/example/java/org/drinkless/tdlib/Log.java b/libs/tdlib/td/example/java/org/drinkless/tdlib/Log.java deleted file mode 100644 index c81ffbeeb7..0000000000 --- a/libs/tdlib/td/example/java/org/drinkless/tdlib/Log.java +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 -// -// 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; - -/** - * Class for managing internal TDLib logging. - */ -public final class Log { - /** - * Changes TDLib log verbosity. - * - * @param verbosityLevel New value of log verbosity level. Must be non-negative. - * Value 0 corresponds to fatal errors, - * value 1 corresponds to java.util.logging.Level.SEVERE, - * value 2 corresponds to java.util.logging.Level.WARNING, - * value 3 corresponds to java.util.logging.Level.INFO, - * value 4 corresponds to java.util.logging.Level.FINE, - * value 5 corresponds to java.util.logging.Level.FINER, - * value greater than 5 can be used to enable even more logging. - * Default value of the log verbosity level is 5. - */ - public static native void setVerbosityLevel(int verbosityLevel); - - /** - * Sets file path for writing TDLib internal log. By default TDLib writes logs to the System.err. - * Use this method to write the log to a file instead. - * - * @param filePath Path to a file for writing TDLib internal log. Use an empty path to - * switch back to logging to the System.err. - * @return whether opening the log file succeeded. - */ - public static native boolean setFilePath(String filePath); - - /** - * Changes maximum size of TDLib log file. - * - * @param maxFileSize Maximum size of the file to where the internal TDLib log is written - * before the file will be auto-rotated. Must be positive. Defaults to 10 MB. - */ - public static native void setMaxFileSize(long maxFileSize); - - /** - * This function is called from the JNI when a fatal error happens to provide a better error message. - * The function does not return. - * - * @param errorMessage Error message. - */ - private static void onFatalError(String errorMessage) { - class ThrowError implements Runnable { - private ThrowError(String errorMessage) { - this.errorMessage = errorMessage; - } - - @Override - public void run() { - throw new RuntimeException("TDLib fatal error: " + errorMessage); - } - - private final String errorMessage; - } - - new Thread(new ThrowError(errorMessage), "TDLib fatal error thread").start(); - while (true) { - try { - Thread.sleep(1000); // milliseconds - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - } -} diff --git a/libs/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java b/libs/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java deleted file mode 100644 index 831de88f1d..0000000000 --- a/libs/tdlib/td/example/java/org/drinkless/tdlib/example/Example.java +++ /dev/null @@ -1,533 +0,0 @@ -// -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 -// -// 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.Log; -import org.drinkless.tdlib.TdApi; - -import java.io.IOError; -import java.io.IOException; -import java.io.BufferedReader; -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.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 quiting = 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<Integer, TdApi.User> users = new ConcurrentHashMap<Integer, TdApi.User>(); - private static final ConcurrentMap<Integer, TdApi.BasicGroup> basicGroups = new ConcurrentHashMap<Integer, TdApi.BasicGroup>(); - private static final ConcurrentMap<Integer, TdApi.Supergroup> supergroups = new ConcurrentHashMap<Integer, TdApi.Supergroup>(); - private static final ConcurrentMap<Integer, TdApi.SecretChat> secretChats = new ConcurrentHashMap<Integer, TdApi.SecretChat>(); - - private static final ConcurrentMap<Long, TdApi.Chat> chats = new ConcurrentHashMap<Long, TdApi.Chat>(); - private static final NavigableSet<OrderedChat> chatList = new TreeSet<OrderedChat>(); - private static boolean haveFullChatList = false; - - private static final ConcurrentMap<Integer, TdApi.UserFullInfo> usersFullInfo = new ConcurrentHashMap<Integer, TdApi.UserFullInfo>(); - private static final ConcurrentMap<Integer, TdApi.BasicGroupFullInfo> basicGroupsFullInfo = new ConcurrentHashMap<Integer, TdApi.BasicGroupFullInfo>(); - private static final ConcurrentMap<Integer, TdApi.SupergroupFullInfo> supergroupsFullInfo = new ConcurrentHashMap<Integer, TdApi.SupergroupFullInfo>(); - - private static final String newLine = System.getProperty("line.separator"); - private static final String commandsLine = "Enter command (gcs - GetChats, gc <chatId> - GetChat, me - GetMe, sm <chatId> <message> - SendMessage, lo - LogOut, q - Quit): "; - private static volatile String currentPrompt = null; - - static { - System.loadLibrary("tdjni"); - } - - 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 setChatOrder(TdApi.Chat chat, long order) { - synchronized (chatList) { - if (chat.order != 0) { - boolean isRemoved = chatList.remove(new OrderedChat(chat.order, chat.id)); - assert isRemoved; - } - - chat.order = order; - - if (chat.order != 0) { - boolean isAdded = chatList.add(new OrderedChat(chat.order, chat.id)); - assert isAdded; - } - } - } - - private static void onAuthorizationStateUpdated(TdApi.AuthorizationState authorizationState) { - if (authorizationState != null) { - Example.authorizationState = authorizationState; - } - switch (Example.authorizationState.getConstructor()) { - case TdApi.AuthorizationStateWaitTdlibParameters.CONSTRUCTOR: - TdApi.TdlibParameters parameters = new TdApi.TdlibParameters(); - parameters.databaseDirectory = "tdlib"; - parameters.useMessageDatabase = true; - parameters.useSecretChats = true; - parameters.apiId = 94575; - parameters.apiHash = "a3406de8d171bb422bb6ddf3bbd800e2"; - parameters.systemLanguageCode = "en"; - parameters.deviceModel = "Desktop"; - parameters.systemVersion = "Unknown"; - parameters.applicationVersion = "1.0"; - parameters.enableStorageOptimizer = true; - - client.send(new TdApi.SetTdlibParameters(parameters), new AuthorizationRequestHandler()); - break; - case TdApi.AuthorizationStateWaitEncryptionKey.CONSTRUCTOR: - client.send(new TdApi.CheckDatabaseEncryptionKey(), new AuthorizationRequestHandler()); - break; - case TdApi.AuthorizationStateWaitPhoneNumber.CONSTRUCTOR: { - String phoneNumber = promptString("Please enter phone number: "); - client.send(new TdApi.SetAuthenticationPhoneNumber(phoneNumber, false, false), 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.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 (!quiting) { - client = Client.create(new UpdatesHandler(), null, null); // recreate client after previous has closed - } - 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]); - } - getChatList(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": - quiting = 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 getChatList(final int limit) { - synchronized (chatList) { - if (!haveFullChatList && limit > chatList.size()) { - // have enough chats in the chat list or chat list is too small - long offsetOrder = Long.MAX_VALUE; - long offsetChatId = 0; - if (!chatList.isEmpty()) { - OrderedChat last = chatList.last(); - offsetOrder = last.order; - offsetChatId = last.chatId; - } - client.send(new TdApi.GetChats(offsetOrder, offsetChatId, limit - chatList.size()), new Client.ResultHandler() { - @Override - public void onResult(TdApi.Object object) { - switch (object.getConstructor()) { - case TdApi.Error.CONSTRUCTOR: - System.err.println("Receive an error for GetChats:" + newLine + object); - break; - case TdApi.Chats.CONSTRUCTOR: - long[] chatIds = ((TdApi.Chats) object).chatIds; - if (chatIds.length == 0) { - synchronized (chatList) { - haveFullChatList = true; - } - } - // chats had already been received through updates, let's retry request - getChatList(limit); - break; - default: - System.err.println("Receive wrong response from TDLib:" + newLine + object); - } - } - }); - return; - } - - // have enough chats in the chat list to answer request - java.util.Iterator<OrderedChat> iter = chatList.iterator(); - System.out.println(); - System.out.println("First " + limit + " chat(s) out of " + chatList.size() + " known chat(s):"); - for (int i = 0; i < limit; 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, false, false, replyMarkup, content), defaultHandler); - } - - public static void main(String[] args) throws InterruptedException { - // disable TDLib log - Log.setVerbosityLevel(0); - if (!Log.setFilePath("tdlib.log")) { - throw new IOError(new IOException("Write access to the current directory is required")); - } - - // create client - client = Client.create(new UpdatesHandler(), 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 (!quiting) { - // await authorization - authorizationLock.lock(); - try { - while (!haveAuthorization) { - gotAuthorization.await(); - } - } finally { - authorizationLock.unlock(); - } - - while (haveAuthorization) { - getCommand(); - } - } - } - - private static class OrderedChat implements Comparable<OrderedChat> { - final long order; - final long chatId; - - OrderedChat(long order, long chatId) { - this.order = order; - this.chatId = chatId; - } - - @Override - public int compareTo(OrderedChat o) { - if (this.order != o.order) { - return o.order < this.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.order == o.order && this.chatId == o.chatId; - } - } - - private static class DefaultHandler implements Client.ResultHandler { - @Override - public void onResult(TdApi.Object object) { - print(object.toString()); - } - } - - private static class UpdatesHandler 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); - - long order = chat.order; - chat.order = 0; - setChatOrder(chat, order); - } - 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; - setChatOrder(chat, updateChat.order); - } - break; - } - case TdApi.UpdateChatOrder.CONSTRUCTOR: { - TdApi.UpdateChatOrder updateChat = (TdApi.UpdateChatOrder) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - setChatOrder(chat, updateChat.order); - } - break; - } - case TdApi.UpdateChatIsPinned.CONSTRUCTOR: { - TdApi.UpdateChatIsPinned updateChat = (TdApi.UpdateChatIsPinned) object; - TdApi.Chat chat = chats.get(updateChat.chatId); - synchronized (chat) { - chat.isPinned = updateChat.isPinned; - setChatOrder(chat, updateChat.order); - } - 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; - setChatOrder(chat, updateChat.order); - } - break; - } - case TdApi.UpdateNotificationSettings.CONSTRUCTOR: { - TdApi.UpdateNotificationSettings update = (TdApi.UpdateNotificationSettings) object; - if (update.scope instanceof TdApi.NotificationSettingsScopeChat) { - TdApi.Chat chat = chats.get(((TdApi.NotificationSettingsScopeChat) update.scope).chatId); - synchronized (chat) { - chat.notificationSettings = update.notificationSettings; - } - } - 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); - } - } - } -}
\ No newline at end of file diff --git a/libs/tdlib/td/example/java/td_jni.cpp b/libs/tdlib/td/example/java/td_jni.cpp deleted file mode 100644 index b9ba74a402..0000000000 --- a/libs/tdlib/td/example/java/td_jni.cpp +++ /dev/null @@ -1,158 +0,0 @@ -// -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018 -// -// 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> - -#include <cstdint> -#include <cstdlib> -#include <string> -#include <utility> - -namespace td_jni { - -static td::td_api::object_ptr<td::td_api::Function> 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::Client *get_client(jlong client_id) { - return reinterpret_cast<td::Client *>(static_cast<std::uintptr_t>(client_id)); -} - -static jlong Client_createNativeClient(JNIEnv *env, jclass clazz) { - return static_cast<jlong>(reinterpret_cast<std::uintptr_t>(new td::Client())); -} - -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 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 - 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); - - jobject object; - response.object->store(env, object); - env->SetObjectArrayElement(events, result_size, object); - env->DeleteLocalRef(object); - - result_size++; - response = client->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); - 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))); -} - -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 jclass log_class; - -static void on_fatal_error(const char *error_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); - } - } -} - -static jint register_native(JavaVM *vm) { - JNIEnv *env; - if (vm->GetEnv(reinterpret_cast<void **>(&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<void *>(function_ptr)); - }; - - 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, "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(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); - td::Log::set_fatal_error_callback(on_fatal_error); - - 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; -} |