2020-07-06 15:02:01 +00:00
|
|
|
// Copyright 2018 Dolphin Emulator Project
|
|
|
|
// Licensed under GPLv2+
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#include "jni/AndroidCommon/IDCache.h"
|
|
|
|
|
|
|
|
#include <jni.h>
|
|
|
|
|
|
|
|
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;
|
2020-07-24 17:58:46 +00:00
|
|
|
static jmethodID s_do_rumble;
|
2020-09-13 11:20:58 +00:00
|
|
|
static jmethodID s_update_touch_pointer;
|
|
|
|
static jmethodID s_on_title_changed;
|
2020-11-06 18:26:56 +00:00
|
|
|
static jmethodID s_finish_emulation_activity;
|
2020-07-06 15:02:01 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2020-07-24 17:58:46 +00:00
|
|
|
static jclass s_linked_hash_map_class;
|
|
|
|
static jmethodID s_linked_hash_map_init;
|
|
|
|
static jmethodID s_linked_hash_map_put;
|
2020-07-06 15:02:01 +00:00
|
|
|
|
2020-07-06 14:57:49 +00:00
|
|
|
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;
|
|
|
|
|
2020-06-25 17:38:02 +00:00
|
|
|
static jclass s_compress_cb_class;
|
|
|
|
static jmethodID s_compress_cb_run;
|
|
|
|
|
2020-06-26 15:52:31 +00:00
|
|
|
static jclass s_content_handler_class;
|
|
|
|
static jmethodID s_content_handler_open_fd;
|
2020-06-27 09:04:48 +00:00
|
|
|
static jmethodID s_content_handler_delete;
|
2020-06-26 15:52:31 +00:00
|
|
|
|
2020-07-06 15:02:01 +00:00
|
|
|
namespace IDCache
|
|
|
|
{
|
|
|
|
JNIEnv* GetEnvForThread()
|
|
|
|
{
|
|
|
|
thread_local static struct OwnedEnv
|
|
|
|
{
|
|
|
|
OwnedEnv()
|
|
|
|
{
|
|
|
|
status = s_java_vm->GetEnv(reinterpret_cast<void**>(&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;
|
|
|
|
}
|
|
|
|
|
2020-07-24 17:58:46 +00:00
|
|
|
jmethodID GetDoRumble()
|
|
|
|
{
|
|
|
|
return s_do_rumble;
|
|
|
|
}
|
|
|
|
|
2020-07-06 15:02:01 +00:00
|
|
|
jmethodID GetUpdateTouchPointer()
|
|
|
|
{
|
2020-09-13 11:20:58 +00:00
|
|
|
return s_update_touch_pointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
jmethodID GetOnTitleChanged()
|
|
|
|
{
|
|
|
|
return s_on_title_changed;
|
2020-07-06 15:02:01 +00:00
|
|
|
}
|
|
|
|
|
2020-11-06 18:26:56 +00:00
|
|
|
jmethodID GetFinishEmulationActivity()
|
|
|
|
{
|
|
|
|
return s_finish_emulation_activity;
|
|
|
|
}
|
|
|
|
|
2020-07-06 15:02:01 +00:00
|
|
|
jclass GetAnalyticsClass()
|
|
|
|
{
|
|
|
|
return s_analytics_class;
|
|
|
|
}
|
|
|
|
|
|
|
|
jmethodID GetSendAnalyticsReport()
|
|
|
|
{
|
|
|
|
return s_send_analytics_report;
|
|
|
|
}
|
|
|
|
|
|
|
|
jmethodID GetAnalyticsValue()
|
|
|
|
{
|
|
|
|
return s_get_analytics_value;
|
|
|
|
}
|
2020-07-06 14:57:49 +00:00
|
|
|
|
2020-07-06 15:02:01 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-07-24 17:58:46 +00:00
|
|
|
jclass GetLinkedHashMapClass()
|
2020-07-06 15:02:01 +00:00
|
|
|
{
|
2020-07-24 17:58:46 +00:00
|
|
|
return s_linked_hash_map_class;
|
|
|
|
}
|
|
|
|
|
|
|
|
jmethodID GetLinkedHashMapInit()
|
|
|
|
{
|
|
|
|
return s_linked_hash_map_init;
|
|
|
|
}
|
|
|
|
|
|
|
|
jmethodID GetLinkedHashMapPut()
|
|
|
|
{
|
|
|
|
return s_linked_hash_map_put;
|
2020-07-06 15:02:01 +00:00
|
|
|
}
|
|
|
|
|
2020-07-06 14:57:49 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-06-25 17:38:02 +00:00
|
|
|
jclass GetCompressCallbackClass()
|
|
|
|
{
|
|
|
|
return s_compress_cb_class;
|
|
|
|
}
|
|
|
|
|
|
|
|
jmethodID GetCompressCallbackRun()
|
|
|
|
{
|
|
|
|
return s_compress_cb_run;
|
|
|
|
}
|
|
|
|
|
2020-06-26 15:52:31 +00:00
|
|
|
jclass GetContentHandlerClass()
|
|
|
|
{
|
|
|
|
return s_content_handler_class;
|
|
|
|
}
|
|
|
|
|
|
|
|
jmethodID GetContentHandlerOpenFd()
|
|
|
|
{
|
|
|
|
return s_content_handler_open_fd;
|
|
|
|
}
|
|
|
|
|
2020-06-27 09:04:48 +00:00
|
|
|
jmethodID GetContentHandlerDelete()
|
|
|
|
{
|
|
|
|
return s_content_handler_delete;
|
|
|
|
}
|
|
|
|
|
2020-07-06 15:02:01 +00:00
|
|
|
} // 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<void**>(&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<jclass>(env->NewGlobalRef(native_library_class));
|
|
|
|
s_display_alert_msg = env->GetStaticMethodID(s_native_library_class, "displayAlertMsg",
|
2020-09-25 15:50:59 +00:00
|
|
|
"(Ljava/lang/String;Ljava/lang/String;ZZ)Z");
|
2020-07-06 15:02:01 +00:00
|
|
|
s_do_rumble = env->GetStaticMethodID(s_native_library_class, "rumble", "(ID)V");
|
2020-09-13 11:20:58 +00:00
|
|
|
s_update_touch_pointer =
|
2020-07-06 15:02:01 +00:00
|
|
|
env->GetStaticMethodID(s_native_library_class, "updateTouchPointer", "()V");
|
2020-09-13 11:20:58 +00:00
|
|
|
s_on_title_changed = env->GetStaticMethodID(s_native_library_class, "onTitleChanged", "()V");
|
2020-11-06 18:26:56 +00:00
|
|
|
s_finish_emulation_activity =
|
|
|
|
env->GetStaticMethodID(s_native_library_class, "finishEmulationActivity", "()V");
|
2020-07-06 14:57:49 +00:00
|
|
|
env->DeleteLocalRef(native_library_class);
|
2020-07-06 15:02:01 +00:00
|
|
|
|
|
|
|
const jclass game_file_class = env->FindClass("org/dolphinemu/dolphinemu/model/GameFile");
|
|
|
|
s_game_file_class = reinterpret_cast<jclass>(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, "<init>", "(J)V");
|
2020-07-06 14:57:49 +00:00
|
|
|
env->DeleteLocalRef(game_file_class);
|
2020-07-06 15:02:01 +00:00
|
|
|
|
|
|
|
const jclass game_file_cache_class =
|
|
|
|
env->FindClass("org/dolphinemu/dolphinemu/model/GameFileCache");
|
|
|
|
s_game_file_cache_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_file_cache_class));
|
|
|
|
s_game_file_cache_pointer = env->GetFieldID(game_file_cache_class, "mPointer", "J");
|
2020-07-06 14:57:49 +00:00
|
|
|
env->DeleteLocalRef(game_file_cache_class);
|
2020-07-06 15:02:01 +00:00
|
|
|
|
|
|
|
const jclass analytics_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Analytics");
|
|
|
|
s_analytics_class = reinterpret_cast<jclass>(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;");
|
2020-07-06 14:57:49 +00:00
|
|
|
env->DeleteLocalRef(analytics_class);
|
|
|
|
|
|
|
|
const jclass ini_file_class = env->FindClass("org/dolphinemu/dolphinemu/utils/IniFile");
|
|
|
|
s_ini_file_class = reinterpret_cast<jclass>(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<jclass>(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, "<init>", "(Lorg/dolphinemu/dolphinemu/utils/IniFile;J)V");
|
|
|
|
env->DeleteLocalRef(ini_file_section_class);
|
2020-07-06 15:02:01 +00:00
|
|
|
|
2020-07-24 17:58:46 +00:00
|
|
|
const jclass map_class = env->FindClass("java/util/LinkedHashMap");
|
|
|
|
s_linked_hash_map_class = reinterpret_cast<jclass>(env->NewGlobalRef(map_class));
|
|
|
|
s_linked_hash_map_init = env->GetMethodID(s_linked_hash_map_class, "<init>", "(I)V");
|
|
|
|
s_linked_hash_map_put = env->GetMethodID(
|
|
|
|
s_linked_hash_map_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
|
|
|
|
2020-06-25 17:38:02 +00:00
|
|
|
const jclass compress_cb_class =
|
|
|
|
env->FindClass("org/dolphinemu/dolphinemu/utils/CompressCallback");
|
|
|
|
s_compress_cb_class = reinterpret_cast<jclass>(env->NewGlobalRef(compress_cb_class));
|
|
|
|
s_compress_cb_run = env->GetMethodID(s_compress_cb_class, "run", "(Ljava/lang/String;F)Z");
|
|
|
|
|
2020-06-26 15:52:31 +00:00
|
|
|
const jclass content_handler_class =
|
|
|
|
env->FindClass("org/dolphinemu/dolphinemu/utils/ContentHandler");
|
|
|
|
s_content_handler_class = reinterpret_cast<jclass>(env->NewGlobalRef(content_handler_class));
|
|
|
|
s_content_handler_open_fd = env->GetStaticMethodID(s_content_handler_class, "openFd",
|
|
|
|
"(Ljava/lang/String;Ljava/lang/String;)I");
|
2020-06-27 09:04:48 +00:00
|
|
|
s_content_handler_delete =
|
|
|
|
env->GetStaticMethodID(s_content_handler_class, "delete", "(Ljava/lang/String;)Z");
|
2020-06-26 15:52:31 +00:00
|
|
|
|
2020-07-06 15:02:01 +00:00
|
|
|
return JNI_VERSION;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JNI_OnUnload(JavaVM* vm, void* reserved)
|
|
|
|
{
|
|
|
|
JNIEnv* env;
|
|
|
|
if (vm->GetEnv(reinterpret_cast<void**>(&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);
|
2020-07-24 17:58:46 +00:00
|
|
|
env->DeleteGlobalRef(s_linked_hash_map_class);
|
2020-07-06 14:57:49 +00:00
|
|
|
env->DeleteGlobalRef(s_ini_file_class);
|
|
|
|
env->DeleteGlobalRef(s_ini_file_section_class);
|
2020-06-25 17:38:02 +00:00
|
|
|
env->DeleteGlobalRef(s_compress_cb_class);
|
2020-06-26 15:52:31 +00:00
|
|
|
env->DeleteGlobalRef(s_content_handler_class);
|
2020-07-06 15:02:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|