// Copyright 2018 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. #include "jni/AndroidCommon/IDCache.h" #include static constexpr jint JNI_VERSION = JNI_VERSION_1_6; static JavaVM* s_java_vm; static jclass s_native_library_class; static jmethodID s_display_alert_msg; static jmethodID s_do_rumble; static jmethodID s_update_touch_pointer; static jmethodID s_on_title_changed; static jmethodID s_finish_emulation_activity; static jclass s_game_file_class; static jfieldID s_game_file_pointer; static jmethodID s_game_file_constructor; static jclass s_game_file_cache_class; static jfieldID s_game_file_cache_pointer; static jclass s_analytics_class; static jmethodID s_send_analytics_report; static jmethodID s_get_analytics_value; static jclass s_linked_hash_map_class; static jmethodID s_linked_hash_map_init; static jmethodID s_linked_hash_map_put; static jclass s_ini_file_class; static jfieldID s_ini_file_pointer; static jclass s_ini_file_section_class; static jfieldID s_ini_file_section_pointer; static jmethodID s_ini_file_section_constructor; static jclass s_compress_cb_class; static jmethodID s_compress_cb_run; static jclass s_content_handler_class; static jmethodID s_content_handler_open_fd; static jmethodID s_content_handler_delete; namespace IDCache { JNIEnv* GetEnvForThread() { thread_local static struct OwnedEnv { OwnedEnv() { status = s_java_vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); if (status == JNI_EDETACHED) s_java_vm->AttachCurrentThread(&env, nullptr); } ~OwnedEnv() { if (status == JNI_EDETACHED) s_java_vm->DetachCurrentThread(); } int status; JNIEnv* env = nullptr; } owned; return owned.env; } jclass GetNativeLibraryClass() { return s_native_library_class; } jmethodID GetDisplayAlertMsg() { return s_display_alert_msg; } jmethodID GetDoRumble() { return s_do_rumble; } jmethodID GetUpdateTouchPointer() { return s_update_touch_pointer; } jmethodID GetOnTitleChanged() { return s_on_title_changed; } jmethodID GetFinishEmulationActivity() { return s_finish_emulation_activity; } jclass GetAnalyticsClass() { return s_analytics_class; } jmethodID GetSendAnalyticsReport() { return s_send_analytics_report; } jmethodID GetAnalyticsValue() { return s_get_analytics_value; } jclass GetGameFileClass() { return s_game_file_class; } jfieldID GetGameFilePointer() { return s_game_file_pointer; } jmethodID GetGameFileConstructor() { return s_game_file_constructor; } jclass GetGameFileCacheClass() { return s_game_file_cache_class; } jfieldID GetGameFileCachePointer() { return s_game_file_cache_pointer; } jclass GetLinkedHashMapClass() { return s_linked_hash_map_class; } jmethodID GetLinkedHashMapInit() { return s_linked_hash_map_init; } jmethodID GetLinkedHashMapPut() { return s_linked_hash_map_put; } jclass GetIniFileClass() { return s_ini_file_class; } jfieldID GetIniFilePointer() { return s_ini_file_pointer; } jclass GetIniFileSectionClass() { return s_ini_file_section_class; } jfieldID GetIniFileSectionPointer() { return s_ini_file_section_pointer; } jmethodID GetIniFileSectionConstructor() { return s_ini_file_section_constructor; } jclass GetCompressCallbackClass() { return s_compress_cb_class; } jmethodID GetCompressCallbackRun() { return s_compress_cb_run; } jclass GetContentHandlerClass() { return s_content_handler_class; } jmethodID GetContentHandlerOpenFd() { return s_content_handler_open_fd; } jmethodID GetContentHandlerDelete() { return s_content_handler_delete; } } // namespace IDCache #ifdef __cplusplus extern "C" { #endif jint JNI_OnLoad(JavaVM* vm, void* reserved) { s_java_vm = vm; JNIEnv* env; if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION) != JNI_OK) return JNI_ERR; const jclass native_library_class = env->FindClass("org/dolphinemu/dolphinemu/NativeLibrary"); s_native_library_class = reinterpret_cast(env->NewGlobalRef(native_library_class)); s_display_alert_msg = env->GetStaticMethodID(s_native_library_class, "displayAlertMsg", "(Ljava/lang/String;Ljava/lang/String;ZZ)Z"); s_do_rumble = env->GetStaticMethodID(s_native_library_class, "rumble", "(ID)V"); s_update_touch_pointer = env->GetStaticMethodID(s_native_library_class, "updateTouchPointer", "()V"); s_on_title_changed = env->GetStaticMethodID(s_native_library_class, "onTitleChanged", "()V"); s_finish_emulation_activity = env->GetStaticMethodID(s_native_library_class, "finishEmulationActivity", "()V"); env->DeleteLocalRef(native_library_class); const jclass game_file_class = env->FindClass("org/dolphinemu/dolphinemu/model/GameFile"); s_game_file_class = reinterpret_cast(env->NewGlobalRef(game_file_class)); s_game_file_pointer = env->GetFieldID(game_file_class, "mPointer", "J"); s_game_file_constructor = env->GetMethodID(game_file_class, "", "(J)V"); env->DeleteLocalRef(game_file_class); const jclass game_file_cache_class = env->FindClass("org/dolphinemu/dolphinemu/model/GameFileCache"); s_game_file_cache_class = reinterpret_cast(env->NewGlobalRef(game_file_cache_class)); s_game_file_cache_pointer = env->GetFieldID(game_file_cache_class, "mPointer", "J"); env->DeleteLocalRef(game_file_cache_class); const jclass analytics_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Analytics"); s_analytics_class = reinterpret_cast(env->NewGlobalRef(analytics_class)); s_send_analytics_report = env->GetStaticMethodID(s_analytics_class, "sendReport", "(Ljava/lang/String;[B)V"); s_get_analytics_value = env->GetStaticMethodID(s_analytics_class, "getValue", "(Ljava/lang/String;)Ljava/lang/String;"); env->DeleteLocalRef(analytics_class); const jclass ini_file_class = env->FindClass("org/dolphinemu/dolphinemu/utils/IniFile"); s_ini_file_class = reinterpret_cast(env->NewGlobalRef(ini_file_class)); s_ini_file_pointer = env->GetFieldID(ini_file_class, "mPointer", "J"); env->DeleteLocalRef(ini_file_class); const jclass ini_file_section_class = env->FindClass("org/dolphinemu/dolphinemu/utils/IniFile$Section"); s_ini_file_section_class = reinterpret_cast(env->NewGlobalRef(ini_file_section_class)); s_ini_file_section_pointer = env->GetFieldID(ini_file_section_class, "mPointer", "J"); s_ini_file_section_constructor = env->GetMethodID( ini_file_section_class, "", "(Lorg/dolphinemu/dolphinemu/utils/IniFile;J)V"); env->DeleteLocalRef(ini_file_section_class); const jclass map_class = env->FindClass("java/util/LinkedHashMap"); s_linked_hash_map_class = reinterpret_cast(env->NewGlobalRef(map_class)); s_linked_hash_map_init = env->GetMethodID(s_linked_hash_map_class, "", "(I)V"); s_linked_hash_map_put = env->GetMethodID( s_linked_hash_map_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); const jclass compress_cb_class = env->FindClass("org/dolphinemu/dolphinemu/utils/CompressCallback"); s_compress_cb_class = reinterpret_cast(env->NewGlobalRef(compress_cb_class)); s_compress_cb_run = env->GetMethodID(s_compress_cb_class, "run", "(Ljava/lang/String;F)Z"); const jclass content_handler_class = env->FindClass("org/dolphinemu/dolphinemu/utils/ContentHandler"); s_content_handler_class = reinterpret_cast(env->NewGlobalRef(content_handler_class)); s_content_handler_open_fd = env->GetStaticMethodID(s_content_handler_class, "openFd", "(Ljava/lang/String;Ljava/lang/String;)I"); s_content_handler_delete = env->GetStaticMethodID(s_content_handler_class, "delete", "(Ljava/lang/String;)Z"); return JNI_VERSION; } void JNI_OnUnload(JavaVM* vm, void* reserved) { JNIEnv* env; if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION) != JNI_OK) return; env->DeleteGlobalRef(s_native_library_class); env->DeleteGlobalRef(s_game_file_class); env->DeleteGlobalRef(s_game_file_cache_class); env->DeleteGlobalRef(s_analytics_class); env->DeleteGlobalRef(s_linked_hash_map_class); env->DeleteGlobalRef(s_ini_file_class); env->DeleteGlobalRef(s_ini_file_section_class); env->DeleteGlobalRef(s_compress_cb_class); env->DeleteGlobalRef(s_content_handler_class); } #ifdef __cplusplus } #endif