id_cache.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <jni.h>
  4. #include "applets/software_keyboard.h"
  5. #include "common/android/id_cache.h"
  6. #include "common/assert.h"
  7. #include "common/fs/fs_android.h"
  8. #include "video_core/rasterizer_interface.h"
  9. static JavaVM* s_java_vm;
  10. static jclass s_native_library_class;
  11. static jclass s_disk_cache_progress_class;
  12. static jclass s_load_callback_stage_class;
  13. static jclass s_game_dir_class;
  14. static jmethodID s_game_dir_constructor;
  15. static jmethodID s_exit_emulation_activity;
  16. static jmethodID s_disk_cache_load_progress;
  17. static jmethodID s_on_emulation_started;
  18. static jmethodID s_on_emulation_stopped;
  19. static jmethodID s_on_program_changed;
  20. static jclass s_game_class;
  21. static jmethodID s_game_constructor;
  22. static jfieldID s_game_title_field;
  23. static jfieldID s_game_path_field;
  24. static jfieldID s_game_program_id_field;
  25. static jfieldID s_game_developer_field;
  26. static jfieldID s_game_version_field;
  27. static jfieldID s_game_is_homebrew_field;
  28. static jclass s_string_class;
  29. static jclass s_pair_class;
  30. static jmethodID s_pair_constructor;
  31. static jfieldID s_pair_first_field;
  32. static jfieldID s_pair_second_field;
  33. static jclass s_overlay_control_data_class;
  34. static jmethodID s_overlay_control_data_constructor;
  35. static jfieldID s_overlay_control_data_id_field;
  36. static jfieldID s_overlay_control_data_enabled_field;
  37. static jfieldID s_overlay_control_data_landscape_position_field;
  38. static jfieldID s_overlay_control_data_portrait_position_field;
  39. static jfieldID s_overlay_control_data_foldable_position_field;
  40. static jclass s_patch_class;
  41. static jmethodID s_patch_constructor;
  42. static jfieldID s_patch_enabled_field;
  43. static jfieldID s_patch_name_field;
  44. static jfieldID s_patch_version_field;
  45. static jfieldID s_patch_type_field;
  46. static jfieldID s_patch_program_id_field;
  47. static jfieldID s_patch_title_id_field;
  48. static jclass s_double_class;
  49. static jmethodID s_double_constructor;
  50. static jfieldID s_double_value_field;
  51. static jclass s_integer_class;
  52. static jmethodID s_integer_constructor;
  53. static jfieldID s_integer_value_field;
  54. static jclass s_boolean_class;
  55. static jmethodID s_boolean_constructor;
  56. static jfieldID s_boolean_value_field;
  57. static constexpr jint JNI_VERSION = JNI_VERSION_1_6;
  58. namespace Common::Android {
  59. JNIEnv* GetEnvForThread() {
  60. thread_local static struct OwnedEnv {
  61. OwnedEnv() {
  62. status = s_java_vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
  63. if (status == JNI_EDETACHED)
  64. s_java_vm->AttachCurrentThread(&env, nullptr);
  65. }
  66. ~OwnedEnv() {
  67. if (status == JNI_EDETACHED)
  68. s_java_vm->DetachCurrentThread();
  69. }
  70. int status;
  71. JNIEnv* env = nullptr;
  72. } owned;
  73. return owned.env;
  74. }
  75. jclass GetNativeLibraryClass() {
  76. return s_native_library_class;
  77. }
  78. jclass GetDiskCacheProgressClass() {
  79. return s_disk_cache_progress_class;
  80. }
  81. jclass GetDiskCacheLoadCallbackStageClass() {
  82. return s_load_callback_stage_class;
  83. }
  84. jclass GetGameDirClass() {
  85. return s_game_dir_class;
  86. }
  87. jmethodID GetGameDirConstructor() {
  88. return s_game_dir_constructor;
  89. }
  90. jmethodID GetExitEmulationActivity() {
  91. return s_exit_emulation_activity;
  92. }
  93. jmethodID GetDiskCacheLoadProgress() {
  94. return s_disk_cache_load_progress;
  95. }
  96. jmethodID GetOnEmulationStarted() {
  97. return s_on_emulation_started;
  98. }
  99. jmethodID GetOnEmulationStopped() {
  100. return s_on_emulation_stopped;
  101. }
  102. jmethodID GetOnProgramChanged() {
  103. return s_on_program_changed;
  104. }
  105. jclass GetGameClass() {
  106. return s_game_class;
  107. }
  108. jmethodID GetGameConstructor() {
  109. return s_game_constructor;
  110. }
  111. jfieldID GetGameTitleField() {
  112. return s_game_title_field;
  113. }
  114. jfieldID GetGamePathField() {
  115. return s_game_path_field;
  116. }
  117. jfieldID GetGameProgramIdField() {
  118. return s_game_program_id_field;
  119. }
  120. jfieldID GetGameDeveloperField() {
  121. return s_game_developer_field;
  122. }
  123. jfieldID GetGameVersionField() {
  124. return s_game_version_field;
  125. }
  126. jfieldID GetGameIsHomebrewField() {
  127. return s_game_is_homebrew_field;
  128. }
  129. jclass GetStringClass() {
  130. return s_string_class;
  131. }
  132. jclass GetPairClass() {
  133. return s_pair_class;
  134. }
  135. jmethodID GetPairConstructor() {
  136. return s_pair_constructor;
  137. }
  138. jfieldID GetPairFirstField() {
  139. return s_pair_first_field;
  140. }
  141. jfieldID GetPairSecondField() {
  142. return s_pair_second_field;
  143. }
  144. jclass GetOverlayControlDataClass() {
  145. return s_overlay_control_data_class;
  146. }
  147. jmethodID GetOverlayControlDataConstructor() {
  148. return s_overlay_control_data_constructor;
  149. }
  150. jfieldID GetOverlayControlDataIdField() {
  151. return s_overlay_control_data_id_field;
  152. }
  153. jfieldID GetOverlayControlDataEnabledField() {
  154. return s_overlay_control_data_enabled_field;
  155. }
  156. jfieldID GetOverlayControlDataLandscapePositionField() {
  157. return s_overlay_control_data_landscape_position_field;
  158. }
  159. jfieldID GetOverlayControlDataPortraitPositionField() {
  160. return s_overlay_control_data_portrait_position_field;
  161. }
  162. jfieldID GetOverlayControlDataFoldablePositionField() {
  163. return s_overlay_control_data_foldable_position_field;
  164. }
  165. jclass GetPatchClass() {
  166. return s_patch_class;
  167. }
  168. jmethodID GetPatchConstructor() {
  169. return s_patch_constructor;
  170. }
  171. jfieldID GetPatchEnabledField() {
  172. return s_patch_enabled_field;
  173. }
  174. jfieldID GetPatchNameField() {
  175. return s_patch_name_field;
  176. }
  177. jfieldID GetPatchVersionField() {
  178. return s_patch_version_field;
  179. }
  180. jfieldID GetPatchTypeField() {
  181. return s_patch_type_field;
  182. }
  183. jfieldID GetPatchProgramIdField() {
  184. return s_patch_program_id_field;
  185. }
  186. jfieldID GetPatchTitleIdField() {
  187. return s_patch_title_id_field;
  188. }
  189. jclass GetDoubleClass() {
  190. return s_double_class;
  191. }
  192. jmethodID GetDoubleConstructor() {
  193. return s_double_constructor;
  194. }
  195. jfieldID GetDoubleValueField() {
  196. return s_double_value_field;
  197. }
  198. jclass GetIntegerClass() {
  199. return s_integer_class;
  200. }
  201. jmethodID GetIntegerConstructor() {
  202. return s_integer_constructor;
  203. }
  204. jfieldID GetIntegerValueField() {
  205. return s_integer_value_field;
  206. }
  207. jclass GetBooleanClass() {
  208. return s_boolean_class;
  209. }
  210. jmethodID GetBooleanConstructor() {
  211. return s_boolean_constructor;
  212. }
  213. jfieldID GetBooleanValueField() {
  214. return s_boolean_value_field;
  215. }
  216. #ifdef __cplusplus
  217. extern "C" {
  218. #endif
  219. jint JNI_OnLoad(JavaVM* vm, void* reserved) {
  220. s_java_vm = vm;
  221. JNIEnv* env;
  222. if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION) != JNI_OK)
  223. return JNI_ERR;
  224. // Initialize Java classes
  225. const jclass native_library_class = env->FindClass("org/yuzu/yuzu_emu/NativeLibrary");
  226. s_native_library_class = reinterpret_cast<jclass>(env->NewGlobalRef(native_library_class));
  227. s_disk_cache_progress_class = reinterpret_cast<jclass>(env->NewGlobalRef(
  228. env->FindClass("org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress")));
  229. s_load_callback_stage_class = reinterpret_cast<jclass>(env->NewGlobalRef(env->FindClass(
  230. "org/yuzu/yuzu_emu/disk_shader_cache/DiskShaderCacheProgress$LoadCallbackStage")));
  231. const jclass game_dir_class = env->FindClass("org/yuzu/yuzu_emu/model/GameDir");
  232. s_game_dir_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_dir_class));
  233. s_game_dir_constructor = env->GetMethodID(game_dir_class, "<init>", "(Ljava/lang/String;Z)V");
  234. env->DeleteLocalRef(game_dir_class);
  235. // Initialize methods
  236. s_exit_emulation_activity =
  237. env->GetStaticMethodID(s_native_library_class, "exitEmulationActivity", "(I)V");
  238. s_disk_cache_load_progress =
  239. env->GetStaticMethodID(s_disk_cache_progress_class, "loadProgress", "(III)V");
  240. s_on_emulation_started =
  241. env->GetStaticMethodID(s_native_library_class, "onEmulationStarted", "()V");
  242. s_on_emulation_stopped =
  243. env->GetStaticMethodID(s_native_library_class, "onEmulationStopped", "(I)V");
  244. s_on_program_changed =
  245. env->GetStaticMethodID(s_native_library_class, "onProgramChanged", "(I)V");
  246. const jclass game_class = env->FindClass("org/yuzu/yuzu_emu/model/Game");
  247. s_game_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_class));
  248. s_game_constructor = env->GetMethodID(game_class, "<init>",
  249. "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
  250. "String;Ljava/lang/String;Ljava/lang/String;Z)V");
  251. s_game_title_field = env->GetFieldID(game_class, "title", "Ljava/lang/String;");
  252. s_game_path_field = env->GetFieldID(game_class, "path", "Ljava/lang/String;");
  253. s_game_program_id_field = env->GetFieldID(game_class, "programId", "Ljava/lang/String;");
  254. s_game_developer_field = env->GetFieldID(game_class, "developer", "Ljava/lang/String;");
  255. s_game_version_field = env->GetFieldID(game_class, "version", "Ljava/lang/String;");
  256. s_game_is_homebrew_field = env->GetFieldID(game_class, "isHomebrew", "Z");
  257. env->DeleteLocalRef(game_class);
  258. const jclass string_class = env->FindClass("java/lang/String");
  259. s_string_class = reinterpret_cast<jclass>(env->NewGlobalRef(string_class));
  260. env->DeleteLocalRef(string_class);
  261. const jclass pair_class = env->FindClass("kotlin/Pair");
  262. s_pair_class = reinterpret_cast<jclass>(env->NewGlobalRef(pair_class));
  263. s_pair_constructor =
  264. env->GetMethodID(pair_class, "<init>", "(Ljava/lang/Object;Ljava/lang/Object;)V");
  265. s_pair_first_field = env->GetFieldID(pair_class, "first", "Ljava/lang/Object;");
  266. s_pair_second_field = env->GetFieldID(pair_class, "second", "Ljava/lang/Object;");
  267. env->DeleteLocalRef(pair_class);
  268. const jclass overlay_control_data_class =
  269. env->FindClass("org/yuzu/yuzu_emu/overlay/model/OverlayControlData");
  270. s_overlay_control_data_class =
  271. reinterpret_cast<jclass>(env->NewGlobalRef(overlay_control_data_class));
  272. s_overlay_control_data_constructor =
  273. env->GetMethodID(overlay_control_data_class, "<init>",
  274. "(Ljava/lang/String;ZLkotlin/Pair;Lkotlin/Pair;Lkotlin/Pair;)V");
  275. s_overlay_control_data_id_field =
  276. env->GetFieldID(overlay_control_data_class, "id", "Ljava/lang/String;");
  277. s_overlay_control_data_enabled_field =
  278. env->GetFieldID(overlay_control_data_class, "enabled", "Z");
  279. s_overlay_control_data_landscape_position_field =
  280. env->GetFieldID(overlay_control_data_class, "landscapePosition", "Lkotlin/Pair;");
  281. s_overlay_control_data_portrait_position_field =
  282. env->GetFieldID(overlay_control_data_class, "portraitPosition", "Lkotlin/Pair;");
  283. s_overlay_control_data_foldable_position_field =
  284. env->GetFieldID(overlay_control_data_class, "foldablePosition", "Lkotlin/Pair;");
  285. env->DeleteLocalRef(overlay_control_data_class);
  286. const jclass patch_class = env->FindClass("org/yuzu/yuzu_emu/model/Patch");
  287. s_patch_class = reinterpret_cast<jclass>(env->NewGlobalRef(patch_class));
  288. s_patch_constructor = env->GetMethodID(
  289. patch_class, "<init>",
  290. "(ZLjava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V");
  291. s_patch_enabled_field = env->GetFieldID(patch_class, "enabled", "Z");
  292. s_patch_name_field = env->GetFieldID(patch_class, "name", "Ljava/lang/String;");
  293. s_patch_version_field = env->GetFieldID(patch_class, "version", "Ljava/lang/String;");
  294. s_patch_type_field = env->GetFieldID(patch_class, "type", "I");
  295. s_patch_program_id_field = env->GetFieldID(patch_class, "programId", "Ljava/lang/String;");
  296. s_patch_title_id_field = env->GetFieldID(patch_class, "titleId", "Ljava/lang/String;");
  297. env->DeleteLocalRef(patch_class);
  298. const jclass double_class = env->FindClass("java/lang/Double");
  299. s_double_class = reinterpret_cast<jclass>(env->NewGlobalRef(double_class));
  300. s_double_constructor = env->GetMethodID(double_class, "<init>", "(D)V");
  301. s_double_value_field = env->GetFieldID(double_class, "value", "D");
  302. env->DeleteLocalRef(double_class);
  303. const jclass int_class = env->FindClass("java/lang/Integer");
  304. s_integer_class = reinterpret_cast<jclass>(env->NewGlobalRef(int_class));
  305. s_integer_constructor = env->GetMethodID(int_class, "<init>", "(I)V");
  306. s_integer_value_field = env->GetFieldID(int_class, "value", "I");
  307. env->DeleteLocalRef(int_class);
  308. const jclass boolean_class = env->FindClass("java/lang/Boolean");
  309. s_boolean_class = reinterpret_cast<jclass>(env->NewGlobalRef(boolean_class));
  310. s_boolean_constructor = env->GetMethodID(boolean_class, "<init>", "(Z)V");
  311. s_boolean_value_field = env->GetFieldID(boolean_class, "value", "Z");
  312. env->DeleteLocalRef(boolean_class);
  313. // Initialize Android Storage
  314. Common::FS::Android::RegisterCallbacks(env, s_native_library_class);
  315. // Initialize applets
  316. Common::Android::SoftwareKeyboard::InitJNI(env);
  317. return JNI_VERSION;
  318. }
  319. void JNI_OnUnload(JavaVM* vm, void* reserved) {
  320. JNIEnv* env;
  321. if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION) != JNI_OK) {
  322. return;
  323. }
  324. // UnInitialize Android Storage
  325. Common::FS::Android::UnRegisterCallbacks();
  326. env->DeleteGlobalRef(s_native_library_class);
  327. env->DeleteGlobalRef(s_disk_cache_progress_class);
  328. env->DeleteGlobalRef(s_load_callback_stage_class);
  329. env->DeleteGlobalRef(s_game_dir_class);
  330. env->DeleteGlobalRef(s_game_class);
  331. env->DeleteGlobalRef(s_string_class);
  332. env->DeleteGlobalRef(s_pair_class);
  333. env->DeleteGlobalRef(s_overlay_control_data_class);
  334. env->DeleteGlobalRef(s_patch_class);
  335. env->DeleteGlobalRef(s_double_class);
  336. env->DeleteGlobalRef(s_integer_class);
  337. env->DeleteGlobalRef(s_boolean_class);
  338. // UnInitialize applets
  339. SoftwareKeyboard::CleanupJNI(env);
  340. }
  341. #ifdef __cplusplus
  342. }
  343. #endif
  344. } // namespace Common::Android