Просмотр исходного кода

Merge pull request #12920 from t895/jni-common

android: Move JNI setup and helpers to common
liamwhite 2 лет назад
Родитель
Сommit
7ec7ff0f30

+ 0 - 6
src/android/app/src/main/jni/CMakeLists.txt

@@ -2,14 +2,8 @@
 # SPDX-License-Identifier: GPL-3.0-or-later
 # SPDX-License-Identifier: GPL-3.0-or-later
 
 
 add_library(yuzu-android SHARED
 add_library(yuzu-android SHARED
-    android_common/android_common.cpp
-    android_common/android_common.h
-    applets/software_keyboard.cpp
-    applets/software_keyboard.h
     emu_window/emu_window.cpp
     emu_window/emu_window.cpp
     emu_window/emu_window.h
     emu_window/emu_window.h
-    id_cache.cpp
-    id_cache.h
     native.cpp
     native.cpp
     native.h
     native.h
     native_config.cpp
     native_config.cpp

+ 3 - 1
src/android/app/src/main/jni/emu_window/emu_window.cpp

@@ -3,6 +3,7 @@
 
 
 #include <android/native_window_jni.h>
 #include <android/native_window_jni.h>
 
 
+#include "common/android/id_cache.h"
 #include "common/logging/log.h"
 #include "common/logging/log.h"
 #include "input_common/drivers/touch_screen.h"
 #include "input_common/drivers/touch_screen.h"
 #include "input_common/drivers/virtual_amiibo.h"
 #include "input_common/drivers/virtual_amiibo.h"
@@ -60,7 +61,8 @@ void EmuWindow_Android::OnRemoveNfcTag() {
 
 
 void EmuWindow_Android::OnFrameDisplayed() {
 void EmuWindow_Android::OnFrameDisplayed() {
     if (!m_first_frame) {
     if (!m_first_frame) {
-        EmulationSession::GetInstance().OnEmulationStarted();
+        Common::Android::RunJNIOnFiber<void>(
+            [&](JNIEnv* env) { EmulationSession::GetInstance().OnEmulationStarted(); });
         m_first_frame = true;
         m_first_frame = true;
     }
     }
 }
 }

+ 13 - 9
src/android/app/src/main/jni/game_metadata.cpp

@@ -1,13 +1,12 @@
 // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 
+#include "common/android/android_common.h"
 #include "core/core.h"
 #include "core/core.h"
 #include "core/file_sys/fs_filesystem.h"
 #include "core/file_sys/fs_filesystem.h"
 #include "core/file_sys/patch_manager.h"
 #include "core/file_sys/patch_manager.h"
 #include "core/loader/loader.h"
 #include "core/loader/loader.h"
 #include "core/loader/nro.h"
 #include "core/loader/nro.h"
-#include "jni.h"
-#include "jni/android_common/android_common.h"
 #include "native.h"
 #include "native.h"
 
 
 struct RomMetadata {
 struct RomMetadata {
@@ -79,7 +78,7 @@ extern "C" {
 jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobject obj,
 jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobject obj,
                                                                jstring jpath) {
                                                                jstring jpath) {
     const auto file = EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
     const auto file = EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
-        GetJString(env, jpath), FileSys::OpenMode::Read);
+        Common::Android::GetJString(env, jpath), FileSys::OpenMode::Read);
     if (!file) {
     if (!file) {
         return false;
         return false;
     }
     }
@@ -104,27 +103,31 @@ jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobj
 
 
 jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getTitle(JNIEnv* env, jobject obj,
 jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getTitle(JNIEnv* env, jobject obj,
                                                             jstring jpath) {
                                                             jstring jpath) {
-    return ToJString(env, GetRomMetadata(GetJString(env, jpath)).title);
+    return Common::Android::ToJString(
+        env, GetRomMetadata(Common::Android::GetJString(env, jpath)).title);
 }
 }
 
 
 jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getProgramId(JNIEnv* env, jobject obj,
 jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getProgramId(JNIEnv* env, jobject obj,
                                                                 jstring jpath) {
                                                                 jstring jpath) {
-    return ToJString(env, std::to_string(GetRomMetadata(GetJString(env, jpath)).programId));
+    return Common::Android::ToJString(
+        env, std::to_string(GetRomMetadata(Common::Android::GetJString(env, jpath)).programId));
 }
 }
 
 
 jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getDeveloper(JNIEnv* env, jobject obj,
 jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getDeveloper(JNIEnv* env, jobject obj,
                                                                 jstring jpath) {
                                                                 jstring jpath) {
-    return ToJString(env, GetRomMetadata(GetJString(env, jpath)).developer);
+    return Common::Android::ToJString(
+        env, GetRomMetadata(Common::Android::GetJString(env, jpath)).developer);
 }
 }
 
 
 jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getVersion(JNIEnv* env, jobject obj,
 jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getVersion(JNIEnv* env, jobject obj,
                                                               jstring jpath, jboolean jreload) {
                                                               jstring jpath, jboolean jreload) {
-    return ToJString(env, GetRomMetadata(GetJString(env, jpath), jreload).version);
+    return Common::Android::ToJString(
+        env, GetRomMetadata(Common::Android::GetJString(env, jpath), jreload).version);
 }
 }
 
 
 jbyteArray Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIcon(JNIEnv* env, jobject obj,
 jbyteArray Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIcon(JNIEnv* env, jobject obj,
                                                               jstring jpath) {
                                                               jstring jpath) {
-    auto icon_data = GetRomMetadata(GetJString(env, jpath)).icon;
+    auto icon_data = GetRomMetadata(Common::Android::GetJString(env, jpath)).icon;
     jbyteArray icon = env->NewByteArray(static_cast<jsize>(icon_data.size()));
     jbyteArray icon = env->NewByteArray(static_cast<jsize>(icon_data.size()));
     env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon),
     env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon),
                             reinterpret_cast<jbyte*>(icon_data.data()));
                             reinterpret_cast<jbyte*>(icon_data.data()));
@@ -133,7 +136,8 @@ jbyteArray Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIcon(JNIEnv* env, jobje
 
 
 jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsHomebrew(JNIEnv* env, jobject obj,
 jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsHomebrew(JNIEnv* env, jobject obj,
                                                                   jstring jpath) {
                                                                   jstring jpath) {
-    return static_cast<jboolean>(GetRomMetadata(GetJString(env, jpath)).isHomebrew);
+    return static_cast<jboolean>(
+        GetRomMetadata(Common::Android::GetJString(env, jpath)).isHomebrew);
 }
 }
 
 
 void Java_org_yuzu_yuzu_1emu_utils_GameMetadata_resetMetadata(JNIEnv* env, jobject obj) {
 void Java_org_yuzu_yuzu_1emu_utils_GameMetadata_resetMetadata(JNIEnv* env, jobject obj) {

+ 68 - 57
src/android/app/src/main/jni/native.cpp

@@ -20,6 +20,8 @@
 #include <frontend_common/content_manager.h>
 #include <frontend_common/content_manager.h>
 #include <jni.h>
 #include <jni.h>
 
 
+#include "common/android/android_common.h"
+#include "common/android/id_cache.h"
 #include "common/detached_tasks.h"
 #include "common/detached_tasks.h"
 #include "common/dynamic_library.h"
 #include "common/dynamic_library.h"
 #include "common/fs/path_util.h"
 #include "common/fs/path_util.h"
@@ -57,8 +59,6 @@
 #include "hid_core/frontend/emulated_controller.h"
 #include "hid_core/frontend/emulated_controller.h"
 #include "hid_core/hid_core.h"
 #include "hid_core/hid_core.h"
 #include "hid_core/hid_types.h"
 #include "hid_core/hid_types.h"
-#include "jni/android_common/android_common.h"
-#include "jni/id_cache.h"
 #include "jni/native.h"
 #include "jni/native.h"
 #include "video_core/renderer_base.h"
 #include "video_core/renderer_base.h"
 #include "video_core/renderer_vulkan/renderer_vulkan.h"
 #include "video_core/renderer_vulkan/renderer_vulkan.h"
@@ -228,7 +228,7 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
         std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window, m_vulkan_library);
         std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window, m_vulkan_library);
 
 
     // Initialize system.
     // Initialize system.
-    jauto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>();
+    jauto android_keyboard = std::make_unique<Common::Android::SoftwareKeyboard::AndroidKeyboard>();
     m_software_keyboard = android_keyboard.get();
     m_software_keyboard = android_keyboard.get();
     m_system.SetShuttingDown(false);
     m_system.SetShuttingDown(false);
     m_system.ApplySettings();
     m_system.ApplySettings();
@@ -411,37 +411,39 @@ void EmulationSession::OnGamepadDisconnectEvent([[maybe_unused]] int index) {
     controller->Disconnect();
     controller->Disconnect();
 }
 }
 
 
-SoftwareKeyboard::AndroidKeyboard* EmulationSession::SoftwareKeyboard() {
+Common::Android::SoftwareKeyboard::AndroidKeyboard* EmulationSession::SoftwareKeyboard() {
     return m_software_keyboard;
     return m_software_keyboard;
 }
 }
 
 
 void EmulationSession::LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress,
 void EmulationSession::LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress,
                                              int max) {
                                              int max) {
-    JNIEnv* env = IDCache::GetEnvForThread();
-    env->CallStaticVoidMethod(IDCache::GetDiskCacheProgressClass(),
-                              IDCache::GetDiskCacheLoadProgress(), static_cast<jint>(stage),
+    JNIEnv* env = Common::Android::GetEnvForThread();
+    env->CallStaticVoidMethod(Common::Android::GetDiskCacheProgressClass(),
+                              Common::Android::GetDiskCacheLoadProgress(), static_cast<jint>(stage),
                               static_cast<jint>(progress), static_cast<jint>(max));
                               static_cast<jint>(progress), static_cast<jint>(max));
 }
 }
 
 
 void EmulationSession::OnEmulationStarted() {
 void EmulationSession::OnEmulationStarted() {
-    JNIEnv* env = IDCache::GetEnvForThread();
-    env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnEmulationStarted());
+    JNIEnv* env = Common::Android::GetEnvForThread();
+    env->CallStaticVoidMethod(Common::Android::GetNativeLibraryClass(),
+                              Common::Android::GetOnEmulationStarted());
 }
 }
 
 
 void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) {
 void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) {
-    JNIEnv* env = IDCache::GetEnvForThread();
-    env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnEmulationStopped(),
-                              static_cast<jint>(result));
+    JNIEnv* env = Common::Android::GetEnvForThread();
+    env->CallStaticVoidMethod(Common::Android::GetNativeLibraryClass(),
+                              Common::Android::GetOnEmulationStopped(), static_cast<jint>(result));
 }
 }
 
 
 void EmulationSession::ChangeProgram(std::size_t program_index) {
 void EmulationSession::ChangeProgram(std::size_t program_index) {
-    JNIEnv* env = IDCache::GetEnvForThread();
-    env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnProgramChanged(),
+    JNIEnv* env = Common::Android::GetEnvForThread();
+    env->CallStaticVoidMethod(Common::Android::GetNativeLibraryClass(),
+                              Common::Android::GetOnProgramChanged(),
                               static_cast<jint>(program_index));
                               static_cast<jint>(program_index));
 }
 }
 
 
 u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) {
 u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) {
-    auto program_id_string = GetJString(env, jprogramId);
+    auto program_id_string = Common::Android::GetJString(env, jprogramId);
     try {
     try {
         return std::stoull(program_id_string);
         return std::stoull(program_id_string);
     } catch (...) {
     } catch (...) {
@@ -491,7 +493,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_surfaceDestroyed(JNIEnv* env, jobject
 
 
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_setAppDirectory(JNIEnv* env, jobject instance,
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_setAppDirectory(JNIEnv* env, jobject instance,
                                                            [[maybe_unused]] jstring j_directory) {
                                                            [[maybe_unused]] jstring j_directory) {
-    Common::FS::SetAppDirectory(GetJString(env, j_directory));
+    Common::FS::SetAppDirectory(Common::Android::GetJString(env, j_directory));
 }
 }
 
 
 int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jobject instance,
 int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jobject instance,
@@ -501,21 +503,22 @@ int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jobject
         jlambdaClass, "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
         jlambdaClass, "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
     const auto callback = [env, jcallback, jlambdaInvokeMethod](size_t max, size_t progress) {
     const auto callback = [env, jcallback, jlambdaInvokeMethod](size_t max, size_t progress) {
         auto jwasCancelled = env->CallObjectMethod(jcallback, jlambdaInvokeMethod,
         auto jwasCancelled = env->CallObjectMethod(jcallback, jlambdaInvokeMethod,
-                                                   ToJDouble(env, max), ToJDouble(env, progress));
-        return GetJBoolean(env, jwasCancelled);
+                                                   Common::Android::ToJDouble(env, max),
+                                                   Common::Android::ToJDouble(env, progress));
+        return Common::Android::GetJBoolean(env, jwasCancelled);
     };
     };
 
 
     return static_cast<int>(
     return static_cast<int>(
         ContentManager::InstallNSP(EmulationSession::GetInstance().System(),
         ContentManager::InstallNSP(EmulationSession::GetInstance().System(),
                                    *EmulationSession::GetInstance().System().GetFilesystem(),
                                    *EmulationSession::GetInstance().System().GetFilesystem(),
-                                   GetJString(env, j_file), callback));
+                                   Common::Android::GetJString(env, j_file), callback));
 }
 }
 
 
 jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* env, jobject jobj,
 jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* env, jobject jobj,
                                                                       jstring jprogramId,
                                                                       jstring jprogramId,
                                                                       jstring jupdatePath) {
                                                                       jstring jupdatePath) {
     u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
     u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
-    std::string updatePath = GetJString(env, jupdatePath);
+    std::string updatePath = Common::Android::GetJString(env, jupdatePath);
     std::shared_ptr<FileSys::NSP> nsp = std::make_shared<FileSys::NSP>(
     std::shared_ptr<FileSys::NSP> nsp = std::make_shared<FileSys::NSP>(
         EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
         EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
             updatePath, FileSys::OpenMode::Read));
             updatePath, FileSys::OpenMode::Read));
@@ -538,8 +541,10 @@ void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeGpuDriver(JNIEnv* e
                                                                        jstring custom_driver_name,
                                                                        jstring custom_driver_name,
                                                                        jstring file_redirect_dir) {
                                                                        jstring file_redirect_dir) {
     EmulationSession::GetInstance().InitializeGpuDriver(
     EmulationSession::GetInstance().InitializeGpuDriver(
-        GetJString(env, hook_lib_dir), GetJString(env, custom_driver_dir),
-        GetJString(env, custom_driver_name), GetJString(env, file_redirect_dir));
+        Common::Android::GetJString(env, hook_lib_dir),
+        Common::Android::GetJString(env, custom_driver_dir),
+        Common::Android::GetJString(env, custom_driver_name),
+        Common::Android::GetJString(env, file_redirect_dir));
 }
 }
 
 
 [[maybe_unused]] static bool CheckKgslPresent() {
 [[maybe_unused]] static bool CheckKgslPresent() {
@@ -566,7 +571,7 @@ jobjectArray Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_getSystemDriverInfo(
     JNIEnv* env, jobject j_obj, jobject j_surf, jstring j_hook_lib_dir) {
     JNIEnv* env, jobject j_obj, jobject j_surf, jstring j_hook_lib_dir) {
     const char* file_redirect_dir_{};
     const char* file_redirect_dir_{};
     int featureFlags{};
     int featureFlags{};
-    std::string hook_lib_dir = GetJString(env, j_hook_lib_dir);
+    std::string hook_lib_dir = Common::Android::GetJString(env, j_hook_lib_dir);
     auto handle = adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(),
     auto handle = adrenotools_open_libvulkan(RTLD_NOW, featureFlags, nullptr, hook_lib_dir.c_str(),
                                              nullptr, nullptr, file_redirect_dir_, nullptr);
                                              nullptr, nullptr, file_redirect_dir_, nullptr);
     auto driver_library = std::make_shared<Common::DynamicLibrary>(handle);
     auto driver_library = std::make_shared<Common::DynamicLibrary>(handle);
@@ -587,9 +592,10 @@ jobjectArray Java_org_yuzu_yuzu_1emu_utils_GpuDriverHelper_getSystemDriverInfo(
         fmt::format("{}.{}.{}", VK_API_VERSION_MAJOR(driver_version),
         fmt::format("{}.{}.{}", VK_API_VERSION_MAJOR(driver_version),
                     VK_API_VERSION_MINOR(driver_version), VK_API_VERSION_PATCH(driver_version));
                     VK_API_VERSION_MINOR(driver_version), VK_API_VERSION_PATCH(driver_version));
 
 
-    jobjectArray j_driver_info =
-        env->NewObjectArray(2, IDCache::GetStringClass(), ToJString(env, version_string));
-    env->SetObjectArrayElement(j_driver_info, 1, ToJString(env, device.GetDriverName()));
+    jobjectArray j_driver_info = env->NewObjectArray(
+        2, Common::Android::GetStringClass(), Common::Android::ToJString(env, version_string));
+    env->SetObjectArrayElement(j_driver_info, 1,
+                               Common::Android::ToJString(env, device.GetDriverName()));
     return j_driver_info;
     return j_driver_info;
 }
 }
 
 
@@ -742,15 +748,15 @@ jdoubleArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPerfStats(JNIEnv* env, jcl
 
 
 jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuBackend(JNIEnv* env, jclass clazz) {
 jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuBackend(JNIEnv* env, jclass clazz) {
     if (Settings::IsNceEnabled()) {
     if (Settings::IsNceEnabled()) {
-        return ToJString(env, "NCE");
+        return Common::Android::ToJString(env, "NCE");
     }
     }
 
 
-    return ToJString(env, "JIT");
+    return Common::Android::ToJString(env, "JIT");
 }
 }
 
 
 jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getGpuDriver(JNIEnv* env, jobject jobj) {
 jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getGpuDriver(JNIEnv* env, jobject jobj) {
-    return ToJString(env,
-                     EmulationSession::GetInstance().System().GPU().Renderer().GetDeviceVendor());
+    return Common::Android::ToJString(
+        env, EmulationSession::GetInstance().System().GPU().Renderer().GetDeviceVendor());
 }
 }
 
 
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_applySettings(JNIEnv* env, jobject jobj) {
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_applySettings(JNIEnv* env, jobject jobj) {
@@ -764,13 +770,14 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_logSettings(JNIEnv* env, jobject jobj
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_run(JNIEnv* env, jobject jobj, jstring j_path,
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_run(JNIEnv* env, jobject jobj, jstring j_path,
                                                jint j_program_index,
                                                jint j_program_index,
                                                jboolean j_frontend_initiated) {
                                                jboolean j_frontend_initiated) {
-    const std::string path = GetJString(env, j_path);
+    const std::string path = Common::Android::GetJString(env, j_path);
 
 
     const Core::SystemResultStatus result{
     const Core::SystemResultStatus result{
         RunEmulation(path, j_program_index, j_frontend_initiated)};
         RunEmulation(path, j_program_index, j_frontend_initiated)};
     if (result != Core::SystemResultStatus::Success) {
     if (result != Core::SystemResultStatus::Success) {
-        env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(),
-                                  IDCache::GetExitEmulationActivity(), static_cast<int>(result));
+        env->CallStaticVoidMethod(Common::Android::GetNativeLibraryClass(),
+                                  Common::Android::GetExitEmulationActivity(),
+                                  static_cast<int>(result));
     }
     }
 }
 }
 
 
@@ -781,7 +788,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_logDeviceInfo(JNIEnv* env, jclass cla
 
 
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_submitInlineKeyboardText(JNIEnv* env, jclass clazz,
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_submitInlineKeyboardText(JNIEnv* env, jclass clazz,
                                                                     jstring j_text) {
                                                                     jstring j_text) {
-    const std::u16string input = Common::UTF8ToUTF16(GetJString(env, j_text));
+    const std::u16string input = Common::UTF8ToUTF16(Common::Android::GetJString(env, j_text));
     EmulationSession::GetInstance().SoftwareKeyboard()->SubmitInlineKeyboardText(input);
     EmulationSession::GetInstance().SoftwareKeyboard()->SubmitInlineKeyboardText(input);
 }
 }
 
 
@@ -815,16 +822,16 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getAppletLaunchPath(JNIEnv* env, j
     auto bis_system =
     auto bis_system =
         EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
         EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
     if (!bis_system) {
     if (!bis_system) {
-        return ToJString(env, "");
+        return Common::Android::ToJString(env, "");
     }
     }
 
 
     auto applet_nca =
     auto applet_nca =
         bis_system->GetEntry(static_cast<u64>(jid), FileSys::ContentRecordType::Program);
         bis_system->GetEntry(static_cast<u64>(jid), FileSys::ContentRecordType::Program);
     if (!applet_nca) {
     if (!applet_nca) {
-        return ToJString(env, "");
+        return Common::Android::ToJString(env, "");
     }
     }
 
 
-    return ToJString(env, applet_nca->GetFullPath());
+    return Common::Android::ToJString(env, applet_nca->GetFullPath());
 }
 }
 
 
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCurrentAppletId(JNIEnv* env, jclass clazz,
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCurrentAppletId(JNIEnv* env, jclass clazz,
@@ -857,7 +864,7 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isFirmwareAvailable(JNIEnv* env,
 jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env, jobject jobj,
 jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env, jobject jobj,
                                                                      jstring jpath,
                                                                      jstring jpath,
                                                                      jstring jprogramId) {
                                                                      jstring jprogramId) {
-    const auto path = GetJString(env, jpath);
+    const auto path = Common::Android::GetJString(env, jpath);
     const auto vFile =
     const auto vFile =
         Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path);
         Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path);
     if (vFile == nullptr) {
     if (vFile == nullptr) {
@@ -875,14 +882,15 @@ jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env
 
 
     auto patches = pm.GetPatches(update_raw);
     auto patches = pm.GetPatches(update_raw);
     jobjectArray jpatchArray =
     jobjectArray jpatchArray =
-        env->NewObjectArray(patches.size(), IDCache::GetPatchClass(), nullptr);
+        env->NewObjectArray(patches.size(), Common::Android::GetPatchClass(), nullptr);
     int i = 0;
     int i = 0;
     for (const auto& patch : patches) {
     for (const auto& patch : patches) {
         jobject jpatch = env->NewObject(
         jobject jpatch = env->NewObject(
-            IDCache::GetPatchClass(), IDCache::GetPatchConstructor(), patch.enabled,
-            ToJString(env, patch.name), ToJString(env, patch.version),
-            static_cast<jint>(patch.type), ToJString(env, std::to_string(patch.program_id)),
-            ToJString(env, std::to_string(patch.title_id)));
+            Common::Android::GetPatchClass(), Common::Android::GetPatchConstructor(), patch.enabled,
+            Common::Android::ToJString(env, patch.name),
+            Common::Android::ToJString(env, patch.version), static_cast<jint>(patch.type),
+            Common::Android::ToJString(env, std::to_string(patch.program_id)),
+            Common::Android::ToJString(env, std::to_string(patch.title_id)));
         env->SetObjectArrayElement(jpatchArray, i, jpatch);
         env->SetObjectArrayElement(jpatchArray, i, jpatch);
         ++i;
         ++i;
     }
     }
@@ -906,7 +914,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_removeMod(JNIEnv* env, jobject jobj,
                                                      jstring jname) {
                                                      jstring jname) {
     auto program_id = EmulationSession::GetProgramId(env, jprogramId);
     auto program_id = EmulationSession::GetProgramId(env, jprogramId);
     ContentManager::RemoveMod(EmulationSession::GetInstance().System().GetFileSystemController(),
     ContentManager::RemoveMod(EmulationSession::GetInstance().System().GetFileSystemController(),
-                              program_id, GetJString(env, jname));
+                              program_id, Common::Android::GetJString(env, jname));
 }
 }
 
 
 jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyInstalledContents(JNIEnv* env,
 jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyInstalledContents(JNIEnv* env,
@@ -917,17 +925,18 @@ jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyInstalledContents(JNIEn
         jlambdaClass, "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
         jlambdaClass, "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
     const auto callback = [env, jcallback, jlambdaInvokeMethod](size_t max, size_t progress) {
     const auto callback = [env, jcallback, jlambdaInvokeMethod](size_t max, size_t progress) {
         auto jwasCancelled = env->CallObjectMethod(jcallback, jlambdaInvokeMethod,
         auto jwasCancelled = env->CallObjectMethod(jcallback, jlambdaInvokeMethod,
-                                                   ToJDouble(env, max), ToJDouble(env, progress));
-        return GetJBoolean(env, jwasCancelled);
+                                                   Common::Android::ToJDouble(env, max),
+                                                   Common::Android::ToJDouble(env, progress));
+        return Common::Android::GetJBoolean(env, jwasCancelled);
     };
     };
 
 
     auto& session = EmulationSession::GetInstance();
     auto& session = EmulationSession::GetInstance();
     std::vector<std::string> result = ContentManager::VerifyInstalledContents(
     std::vector<std::string> result = ContentManager::VerifyInstalledContents(
         session.System(), *session.GetContentProvider(), callback);
         session.System(), *session.GetContentProvider(), callback);
-    jobjectArray jresult =
-        env->NewObjectArray(result.size(), IDCache::GetStringClass(), ToJString(env, ""));
+    jobjectArray jresult = env->NewObjectArray(result.size(), Common::Android::GetStringClass(),
+                                               Common::Android::ToJString(env, ""));
     for (size_t i = 0; i < result.size(); ++i) {
     for (size_t i = 0; i < result.size(); ++i) {
-        env->SetObjectArrayElement(jresult, i, ToJString(env, result[i]));
+        env->SetObjectArrayElement(jresult, i, Common::Android::ToJString(env, result[i]));
     }
     }
     return jresult;
     return jresult;
 }
 }
@@ -939,19 +948,20 @@ jint Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyGameContents(JNIEnv* env, jobje
         jlambdaClass, "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
         jlambdaClass, "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
     const auto callback = [env, jcallback, jlambdaInvokeMethod](size_t max, size_t progress) {
     const auto callback = [env, jcallback, jlambdaInvokeMethod](size_t max, size_t progress) {
         auto jwasCancelled = env->CallObjectMethod(jcallback, jlambdaInvokeMethod,
         auto jwasCancelled = env->CallObjectMethod(jcallback, jlambdaInvokeMethod,
-                                                   ToJDouble(env, max), ToJDouble(env, progress));
-        return GetJBoolean(env, jwasCancelled);
+                                                   Common::Android::ToJDouble(env, max),
+                                                   Common::Android::ToJDouble(env, progress));
+        return Common::Android::GetJBoolean(env, jwasCancelled);
     };
     };
     auto& session = EmulationSession::GetInstance();
     auto& session = EmulationSession::GetInstance();
-    return static_cast<jint>(
-        ContentManager::VerifyGameContents(session.System(), GetJString(env, jpath), callback));
+    return static_cast<jint>(ContentManager::VerifyGameContents(
+        session.System(), Common::Android::GetJString(env, jpath), callback));
 }
 }
 
 
 jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject jobj,
 jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject jobj,
                                                           jstring jprogramId) {
                                                           jstring jprogramId) {
     auto program_id = EmulationSession::GetProgramId(env, jprogramId);
     auto program_id = EmulationSession::GetProgramId(env, jprogramId);
     if (program_id == 0) {
     if (program_id == 0) {
-        return ToJString(env, "");
+        return Common::Android::ToJString(env, "");
     }
     }
 
 
     auto& system = EmulationSession::GetInstance().System();
     auto& system = EmulationSession::GetInstance().System();
@@ -968,7 +978,7 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject j
     const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
     const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
         {}, vfsNandDir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
         {}, vfsNandDir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
         program_id, user_id->AsU128(), 0);
         program_id, user_id->AsU128(), 0);
-    return ToJString(env, user_save_data_path);
+    return Common::Android::ToJString(env, user_save_data_path);
 }
 }
 
 
 jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getDefaultProfileSaveDataRoot(JNIEnv* env,
 jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getDefaultProfileSaveDataRoot(JNIEnv* env,
@@ -981,12 +991,13 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getDefaultProfileSaveDataRoot(JNIE
 
 
     const auto user_save_data_root =
     const auto user_save_data_root =
         FileSys::SaveDataFactory::GetUserGameSaveDataRoot(user_id->AsU128(), jfuture);
         FileSys::SaveDataFactory::GetUserGameSaveDataRoot(user_id->AsU128(), jfuture);
-    return ToJString(env, user_save_data_root);
+    return Common::Android::ToJString(env, user_save_data_root);
 }
 }
 
 
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_addFileToFilesystemProvider(JNIEnv* env, jobject jobj,
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_addFileToFilesystemProvider(JNIEnv* env, jobject jobj,
                                                                        jstring jpath) {
                                                                        jstring jpath) {
-    EmulationSession::GetInstance().ConfigureFilesystemProvider(GetJString(env, jpath));
+    EmulationSession::GetInstance().ConfigureFilesystemProvider(
+        Common::Android::GetJString(env, jpath));
 }
 }
 
 
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_clearFilesystemProvider(JNIEnv* env, jobject jobj) {
 void Java_org_yuzu_yuzu_1emu_NativeLibrary_clearFilesystemProvider(JNIEnv* env, jobject jobj) {

+ 3 - 3
src/android/app/src/main/jni/native.h

@@ -2,13 +2,13 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 
 #include <android/native_window_jni.h>
 #include <android/native_window_jni.h>
+#include "common/android/applets/software_keyboard.h"
 #include "common/detached_tasks.h"
 #include "common/detached_tasks.h"
 #include "core/core.h"
 #include "core/core.h"
 #include "core/file_sys/registered_cache.h"
 #include "core/file_sys/registered_cache.h"
 #include "core/hle/service/acc/profile_manager.h"
 #include "core/hle/service/acc/profile_manager.h"
 #include "core/perf_stats.h"
 #include "core/perf_stats.h"
 #include "frontend_common/content_manager.h"
 #include "frontend_common/content_manager.h"
-#include "jni/applets/software_keyboard.h"
 #include "jni/emu_window/emu_window.h"
 #include "jni/emu_window/emu_window.h"
 #include "video_core/rasterizer_interface.h"
 #include "video_core/rasterizer_interface.h"
 
 
@@ -54,7 +54,7 @@ public:
     void SetDeviceType([[maybe_unused]] int index, int type);
     void SetDeviceType([[maybe_unused]] int index, int type);
     void OnGamepadConnectEvent([[maybe_unused]] int index);
     void OnGamepadConnectEvent([[maybe_unused]] int index);
     void OnGamepadDisconnectEvent([[maybe_unused]] int index);
     void OnGamepadDisconnectEvent([[maybe_unused]] int index);
-    SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard();
+    Common::Android::SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard();
 
 
     static void OnEmulationStarted();
     static void OnEmulationStarted();
 
 
@@ -79,7 +79,7 @@ private:
     Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
     Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
     std::atomic<bool> m_is_running = false;
     std::atomic<bool> m_is_running = false;
     std::atomic<bool> m_is_paused = false;
     std::atomic<bool> m_is_paused = false;
-    SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
+    Common::Android::SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
     std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
     std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
     int m_applet_id{1};
     int m_applet_id{1};
 
 

+ 66 - 55
src/android/app/src/main/jni/native_config.cpp

@@ -8,11 +8,11 @@
 
 
 #include "android_config.h"
 #include "android_config.h"
 #include "android_settings.h"
 #include "android_settings.h"
+#include "common/android/android_common.h"
+#include "common/android/id_cache.h"
 #include "common/logging/log.h"
 #include "common/logging/log.h"
 #include "common/settings.h"
 #include "common/settings.h"
 #include "frontend_common/config.h"
 #include "frontend_common/config.h"
-#include "jni/android_common/android_common.h"
-#include "jni/id_cache.h"
 #include "native.h"
 #include "native.h"
 
 
 std::unique_ptr<AndroidConfig> global_config;
 std::unique_ptr<AndroidConfig> global_config;
@@ -20,7 +20,7 @@ std::unique_ptr<AndroidConfig> per_game_config;
 
 
 template <typename T>
 template <typename T>
 Settings::Setting<T>* getSetting(JNIEnv* env, jstring jkey) {
 Settings::Setting<T>* getSetting(JNIEnv* env, jstring jkey) {
-    auto key = GetJString(env, jkey);
+    auto key = Common::Android::GetJString(env, jkey);
     auto basic_setting = Settings::values.linkage.by_key[key];
     auto basic_setting = Settings::values.linkage.by_key[key];
     if (basic_setting != 0) {
     if (basic_setting != 0) {
         return static_cast<Settings::Setting<T>*>(basic_setting);
         return static_cast<Settings::Setting<T>*>(basic_setting);
@@ -55,7 +55,7 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_initializePerGameConfig(JNIEnv*
                                                                         jstring jprogramId,
                                                                         jstring jprogramId,
                                                                         jstring jfileName) {
                                                                         jstring jfileName) {
     auto program_id = EmulationSession::GetProgramId(env, jprogramId);
     auto program_id = EmulationSession::GetProgramId(env, jprogramId);
-    auto file_name = GetJString(env, jfileName);
+    auto file_name = Common::Android::GetJString(env, jfileName);
     const auto config_file_name = program_id == 0 ? file_name : fmt::format("{:016X}", program_id);
     const auto config_file_name = program_id == 0 ? file_name : fmt::format("{:016X}", program_id);
     per_game_config =
     per_game_config =
         std::make_unique<AndroidConfig>(config_file_name, Config::ConfigType::PerGameConfig);
         std::make_unique<AndroidConfig>(config_file_name, Config::ConfigType::PerGameConfig);
@@ -186,9 +186,9 @@ jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getString(JNIEnv* env, jobjec
                                                              jboolean needGlobal) {
                                                              jboolean needGlobal) {
     auto setting = getSetting<std::string>(env, jkey);
     auto setting = getSetting<std::string>(env, jkey);
     if (setting == nullptr) {
     if (setting == nullptr) {
-        return ToJString(env, "");
+        return Common::Android::ToJString(env, "");
     }
     }
-    return ToJString(env, setting->GetValue(static_cast<bool>(needGlobal)));
+    return Common::Android::ToJString(env, setting->GetValue(static_cast<bool>(needGlobal)));
 }
 }
 
 
 void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setString(JNIEnv* env, jobject obj, jstring jkey,
 void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setString(JNIEnv* env, jobject obj, jstring jkey,
@@ -198,7 +198,7 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setString(JNIEnv* env, jobject o
         return;
         return;
     }
     }
 
 
-    setting->SetValue(GetJString(env, value));
+    setting->SetValue(Common::Android::GetJString(env, value));
 }
 }
 
 
 jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getIsRuntimeModifiable(JNIEnv* env, jobject obj,
 jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getIsRuntimeModifiable(JNIEnv* env, jobject obj,
@@ -214,13 +214,13 @@ jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getPairedSettingKey(JNIEnv* e
                                                                        jstring jkey) {
                                                                        jstring jkey) {
     auto setting = getSetting<std::string>(env, jkey);
     auto setting = getSetting<std::string>(env, jkey);
     if (setting == nullptr) {
     if (setting == nullptr) {
-        return ToJString(env, "");
+        return Common::Android::ToJString(env, "");
     }
     }
     if (setting->PairedSetting() == nullptr) {
     if (setting->PairedSetting() == nullptr) {
-        return ToJString(env, "");
+        return Common::Android::ToJString(env, "");
     }
     }
 
 
-    return ToJString(env, setting->PairedSetting()->GetLabel());
+    return Common::Android::ToJString(env, setting->PairedSetting()->GetLabel());
 }
 }
 
 
 jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getIsSwitchable(JNIEnv* env, jobject obj,
 jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getIsSwitchable(JNIEnv* env, jobject obj,
@@ -262,21 +262,21 @@ jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getDefaultToString(JNIEnv* en
                                                                       jstring jkey) {
                                                                       jstring jkey) {
     auto setting = getSetting<std::string>(env, jkey);
     auto setting = getSetting<std::string>(env, jkey);
     if (setting != nullptr) {
     if (setting != nullptr) {
-        return ToJString(env, setting->DefaultToString());
+        return Common::Android::ToJString(env, setting->DefaultToString());
     }
     }
-    return ToJString(env, "");
+    return Common::Android::ToJString(env, "");
 }
 }
 
 
 jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getGameDirs(JNIEnv* env, jobject obj) {
 jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getGameDirs(JNIEnv* env, jobject obj) {
-    jclass gameDirClass = IDCache::GetGameDirClass();
-    jmethodID gameDirConstructor = IDCache::GetGameDirConstructor();
+    jclass gameDirClass = Common::Android::GetGameDirClass();
+    jmethodID gameDirConstructor = Common::Android::GetGameDirConstructor();
     jobjectArray jgameDirArray =
     jobjectArray jgameDirArray =
         env->NewObjectArray(AndroidSettings::values.game_dirs.size(), gameDirClass, nullptr);
         env->NewObjectArray(AndroidSettings::values.game_dirs.size(), gameDirClass, nullptr);
     for (size_t i = 0; i < AndroidSettings::values.game_dirs.size(); ++i) {
     for (size_t i = 0; i < AndroidSettings::values.game_dirs.size(); ++i) {
-        jobject jgameDir =
-            env->NewObject(gameDirClass, gameDirConstructor,
-                           ToJString(env, AndroidSettings::values.game_dirs[i].path),
-                           static_cast<jboolean>(AndroidSettings::values.game_dirs[i].deep_scan));
+        jobject jgameDir = env->NewObject(
+            gameDirClass, gameDirConstructor,
+            Common::Android::ToJString(env, AndroidSettings::values.game_dirs[i].path),
+            static_cast<jboolean>(AndroidSettings::values.game_dirs[i].deep_scan));
         env->SetObjectArrayElement(jgameDirArray, i, jgameDir);
         env->SetObjectArrayElement(jgameDirArray, i, jgameDir);
     }
     }
     return jgameDirArray;
     return jgameDirArray;
@@ -292,14 +292,14 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setGameDirs(JNIEnv* env, jobject
     }
     }
 
 
     jobject dir = env->GetObjectArrayElement(gameDirs, 0);
     jobject dir = env->GetObjectArrayElement(gameDirs, 0);
-    jclass gameDirClass = IDCache::GetGameDirClass();
+    jclass gameDirClass = Common::Android::GetGameDirClass();
     jfieldID uriStringField = env->GetFieldID(gameDirClass, "uriString", "Ljava/lang/String;");
     jfieldID uriStringField = env->GetFieldID(gameDirClass, "uriString", "Ljava/lang/String;");
     jfieldID deepScanBooleanField = env->GetFieldID(gameDirClass, "deepScan", "Z");
     jfieldID deepScanBooleanField = env->GetFieldID(gameDirClass, "deepScan", "Z");
     for (int i = 0; i < size; ++i) {
     for (int i = 0; i < size; ++i) {
         dir = env->GetObjectArrayElement(gameDirs, i);
         dir = env->GetObjectArrayElement(gameDirs, i);
         jstring juriString = static_cast<jstring>(env->GetObjectField(dir, uriStringField));
         jstring juriString = static_cast<jstring>(env->GetObjectField(dir, uriStringField));
         jboolean jdeepScanBoolean = env->GetBooleanField(dir, deepScanBooleanField);
         jboolean jdeepScanBoolean = env->GetBooleanField(dir, deepScanBooleanField);
-        std::string uriString = GetJString(env, juriString);
+        std::string uriString = Common::Android::GetJString(env, juriString);
         AndroidSettings::values.game_dirs.push_back(
         AndroidSettings::values.game_dirs.push_back(
             AndroidSettings::GameDir{uriString, static_cast<bool>(jdeepScanBoolean)});
             AndroidSettings::GameDir{uriString, static_cast<bool>(jdeepScanBoolean)});
     }
     }
@@ -307,13 +307,13 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setGameDirs(JNIEnv* env, jobject
 
 
 void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_addGameDir(JNIEnv* env, jobject obj,
 void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_addGameDir(JNIEnv* env, jobject obj,
                                                            jobject gameDir) {
                                                            jobject gameDir) {
-    jclass gameDirClass = IDCache::GetGameDirClass();
+    jclass gameDirClass = Common::Android::GetGameDirClass();
     jfieldID uriStringField = env->GetFieldID(gameDirClass, "uriString", "Ljava/lang/String;");
     jfieldID uriStringField = env->GetFieldID(gameDirClass, "uriString", "Ljava/lang/String;");
     jfieldID deepScanBooleanField = env->GetFieldID(gameDirClass, "deepScan", "Z");
     jfieldID deepScanBooleanField = env->GetFieldID(gameDirClass, "deepScan", "Z");
 
 
     jstring juriString = static_cast<jstring>(env->GetObjectField(gameDir, uriStringField));
     jstring juriString = static_cast<jstring>(env->GetObjectField(gameDir, uriStringField));
     jboolean jdeepScanBoolean = env->GetBooleanField(gameDir, deepScanBooleanField);
     jboolean jdeepScanBoolean = env->GetBooleanField(gameDir, deepScanBooleanField);
-    std::string uriString = GetJString(env, juriString);
+    std::string uriString = Common::Android::GetJString(env, juriString);
     AndroidSettings::values.game_dirs.push_back(
     AndroidSettings::values.game_dirs.push_back(
         AndroidSettings::GameDir{uriString, static_cast<bool>(jdeepScanBoolean)});
         AndroidSettings::GameDir{uriString, static_cast<bool>(jdeepScanBoolean)});
 }
 }
@@ -323,9 +323,11 @@ jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getDisabledAddons(JNIEnv
     auto program_id = EmulationSession::GetProgramId(env, jprogramId);
     auto program_id = EmulationSession::GetProgramId(env, jprogramId);
     auto& disabledAddons = Settings::values.disabled_addons[program_id];
     auto& disabledAddons = Settings::values.disabled_addons[program_id];
     jobjectArray jdisabledAddonsArray =
     jobjectArray jdisabledAddonsArray =
-        env->NewObjectArray(disabledAddons.size(), IDCache::GetStringClass(), ToJString(env, ""));
+        env->NewObjectArray(disabledAddons.size(), Common::Android::GetStringClass(),
+                            Common::Android::ToJString(env, ""));
     for (size_t i = 0; i < disabledAddons.size(); ++i) {
     for (size_t i = 0; i < disabledAddons.size(); ++i) {
-        env->SetObjectArrayElement(jdisabledAddonsArray, i, ToJString(env, disabledAddons[i]));
+        env->SetObjectArrayElement(jdisabledAddonsArray, i,
+                                   Common::Android::ToJString(env, disabledAddons[i]));
     }
     }
     return jdisabledAddonsArray;
     return jdisabledAddonsArray;
 }
 }
@@ -339,7 +341,7 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setDisabledAddons(JNIEnv* env, j
     const int size = env->GetArrayLength(jdisabledAddons);
     const int size = env->GetArrayLength(jdisabledAddons);
     for (int i = 0; i < size; ++i) {
     for (int i = 0; i < size; ++i) {
         auto jaddon = static_cast<jstring>(env->GetObjectArrayElement(jdisabledAddons, i));
         auto jaddon = static_cast<jstring>(env->GetObjectArrayElement(jdisabledAddons, i));
-        disabled_addons.push_back(GetJString(env, jaddon));
+        disabled_addons.push_back(Common::Android::GetJString(env, jaddon));
     }
     }
     Settings::values.disabled_addons[program_id] = disabled_addons;
     Settings::values.disabled_addons[program_id] = disabled_addons;
 }
 }
@@ -348,26 +350,27 @@ jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getOverlayControlData(JN
                                                                               jobject obj) {
                                                                               jobject obj) {
     jobjectArray joverlayControlDataArray =
     jobjectArray joverlayControlDataArray =
         env->NewObjectArray(AndroidSettings::values.overlay_control_data.size(),
         env->NewObjectArray(AndroidSettings::values.overlay_control_data.size(),
-                            IDCache::GetOverlayControlDataClass(), nullptr);
+                            Common::Android::GetOverlayControlDataClass(), nullptr);
     for (size_t i = 0; i < AndroidSettings::values.overlay_control_data.size(); ++i) {
     for (size_t i = 0; i < AndroidSettings::values.overlay_control_data.size(); ++i) {
         const auto& control_data = AndroidSettings::values.overlay_control_data[i];
         const auto& control_data = AndroidSettings::values.overlay_control_data[i];
         jobject jlandscapePosition =
         jobject jlandscapePosition =
-            env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(),
-                           ToJDouble(env, control_data.landscape_position.first),
-                           ToJDouble(env, control_data.landscape_position.second));
+            env->NewObject(Common::Android::GetPairClass(), Common::Android::GetPairConstructor(),
+                           Common::Android::ToJDouble(env, control_data.landscape_position.first),
+                           Common::Android::ToJDouble(env, control_data.landscape_position.second));
         jobject jportraitPosition =
         jobject jportraitPosition =
-            env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(),
-                           ToJDouble(env, control_data.portrait_position.first),
-                           ToJDouble(env, control_data.portrait_position.second));
+            env->NewObject(Common::Android::GetPairClass(), Common::Android::GetPairConstructor(),
+                           Common::Android::ToJDouble(env, control_data.portrait_position.first),
+                           Common::Android::ToJDouble(env, control_data.portrait_position.second));
         jobject jfoldablePosition =
         jobject jfoldablePosition =
-            env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(),
-                           ToJDouble(env, control_data.foldable_position.first),
-                           ToJDouble(env, control_data.foldable_position.second));
-
-        jobject jcontrolData = env->NewObject(
-            IDCache::GetOverlayControlDataClass(), IDCache::GetOverlayControlDataConstructor(),
-            ToJString(env, control_data.id), control_data.enabled, jlandscapePosition,
-            jportraitPosition, jfoldablePosition);
+            env->NewObject(Common::Android::GetPairClass(), Common::Android::GetPairConstructor(),
+                           Common::Android::ToJDouble(env, control_data.foldable_position.first),
+                           Common::Android::ToJDouble(env, control_data.foldable_position.second));
+
+        jobject jcontrolData =
+            env->NewObject(Common::Android::GetOverlayControlDataClass(),
+                           Common::Android::GetOverlayControlDataConstructor(),
+                           Common::Android::ToJString(env, control_data.id), control_data.enabled,
+                           jlandscapePosition, jportraitPosition, jfoldablePosition);
         env->SetObjectArrayElement(joverlayControlDataArray, i, jcontrolData);
         env->SetObjectArrayElement(joverlayControlDataArray, i, jcontrolData);
     }
     }
     return joverlayControlDataArray;
     return joverlayControlDataArray;
@@ -384,33 +387,41 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setOverlayControlData(
 
 
     for (int i = 0; i < size; ++i) {
     for (int i = 0; i < size; ++i) {
         jobject joverlayControlData = env->GetObjectArrayElement(joverlayControlDataArray, i);
         jobject joverlayControlData = env->GetObjectArrayElement(joverlayControlDataArray, i);
-        jstring jidString = static_cast<jstring>(
-            env->GetObjectField(joverlayControlData, IDCache::GetOverlayControlDataIdField()));
+        jstring jidString = static_cast<jstring>(env->GetObjectField(
+            joverlayControlData, Common::Android::GetOverlayControlDataIdField()));
         bool enabled = static_cast<bool>(env->GetBooleanField(
         bool enabled = static_cast<bool>(env->GetBooleanField(
-            joverlayControlData, IDCache::GetOverlayControlDataEnabledField()));
+            joverlayControlData, Common::Android::GetOverlayControlDataEnabledField()));
 
 
         jobject jlandscapePosition = env->GetObjectField(
         jobject jlandscapePosition = env->GetObjectField(
-            joverlayControlData, IDCache::GetOverlayControlDataLandscapePositionField());
+            joverlayControlData, Common::Android::GetOverlayControlDataLandscapePositionField());
         std::pair<double, double> landscape_position = std::make_pair(
         std::pair<double, double> landscape_position = std::make_pair(
-            GetJDouble(env, env->GetObjectField(jlandscapePosition, IDCache::GetPairFirstField())),
-            GetJDouble(env,
-                       env->GetObjectField(jlandscapePosition, IDCache::GetPairSecondField())));
+            Common::Android::GetJDouble(
+                env, env->GetObjectField(jlandscapePosition, Common::Android::GetPairFirstField())),
+            Common::Android::GetJDouble(
+                env,
+                env->GetObjectField(jlandscapePosition, Common::Android::GetPairSecondField())));
 
 
         jobject jportraitPosition = env->GetObjectField(
         jobject jportraitPosition = env->GetObjectField(
-            joverlayControlData, IDCache::GetOverlayControlDataPortraitPositionField());
+            joverlayControlData, Common::Android::GetOverlayControlDataPortraitPositionField());
         std::pair<double, double> portrait_position = std::make_pair(
         std::pair<double, double> portrait_position = std::make_pair(
-            GetJDouble(env, env->GetObjectField(jportraitPosition, IDCache::GetPairFirstField())),
-            GetJDouble(env, env->GetObjectField(jportraitPosition, IDCache::GetPairSecondField())));
+            Common::Android::GetJDouble(
+                env, env->GetObjectField(jportraitPosition, Common::Android::GetPairFirstField())),
+            Common::Android::GetJDouble(
+                env,
+                env->GetObjectField(jportraitPosition, Common::Android::GetPairSecondField())));
 
 
         jobject jfoldablePosition = env->GetObjectField(
         jobject jfoldablePosition = env->GetObjectField(
-            joverlayControlData, IDCache::GetOverlayControlDataFoldablePositionField());
+            joverlayControlData, Common::Android::GetOverlayControlDataFoldablePositionField());
         std::pair<double, double> foldable_position = std::make_pair(
         std::pair<double, double> foldable_position = std::make_pair(
-            GetJDouble(env, env->GetObjectField(jfoldablePosition, IDCache::GetPairFirstField())),
-            GetJDouble(env, env->GetObjectField(jfoldablePosition, IDCache::GetPairSecondField())));
+            Common::Android::GetJDouble(
+                env, env->GetObjectField(jfoldablePosition, Common::Android::GetPairFirstField())),
+            Common::Android::GetJDouble(
+                env,
+                env->GetObjectField(jfoldablePosition, Common::Android::GetPairSecondField())));
 
 
         AndroidSettings::values.overlay_control_data.push_back(AndroidSettings::OverlayControlData{
         AndroidSettings::values.overlay_control_data.push_back(AndroidSettings::OverlayControlData{
-            GetJString(env, jidString), enabled, landscape_position, portrait_position,
-            foldable_position});
+            Common::Android::GetJString(env, jidString), enabled, landscape_position,
+            portrait_position, foldable_position});
     }
     }
 }
 }
 
 

+ 6 - 7
src/android/app/src/main/jni/native_log.cpp

@@ -1,31 +1,30 @@
 // SPDX-FileCopyrightText: 2023 yuzu Emulator Project
 // SPDX-FileCopyrightText: 2023 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 
+#include <common/android/android_common.h>
 #include <common/logging/log.h>
 #include <common/logging/log.h>
 #include <jni.h>
 #include <jni.h>
 
 
-#include "android_common/android_common.h"
-
 extern "C" {
 extern "C" {
 
 
 void Java_org_yuzu_yuzu_1emu_utils_Log_debug(JNIEnv* env, jobject obj, jstring jmessage) {
 void Java_org_yuzu_yuzu_1emu_utils_Log_debug(JNIEnv* env, jobject obj, jstring jmessage) {
-    LOG_DEBUG(Frontend, "{}", GetJString(env, jmessage));
+    LOG_DEBUG(Frontend, "{}", Common::Android::GetJString(env, jmessage));
 }
 }
 
 
 void Java_org_yuzu_yuzu_1emu_utils_Log_warning(JNIEnv* env, jobject obj, jstring jmessage) {
 void Java_org_yuzu_yuzu_1emu_utils_Log_warning(JNIEnv* env, jobject obj, jstring jmessage) {
-    LOG_WARNING(Frontend, "{}", GetJString(env, jmessage));
+    LOG_WARNING(Frontend, "{}", Common::Android::GetJString(env, jmessage));
 }
 }
 
 
 void Java_org_yuzu_yuzu_1emu_utils_Log_info(JNIEnv* env, jobject obj, jstring jmessage) {
 void Java_org_yuzu_yuzu_1emu_utils_Log_info(JNIEnv* env, jobject obj, jstring jmessage) {
-    LOG_INFO(Frontend, "{}", GetJString(env, jmessage));
+    LOG_INFO(Frontend, "{}", Common::Android::GetJString(env, jmessage));
 }
 }
 
 
 void Java_org_yuzu_yuzu_1emu_utils_Log_error(JNIEnv* env, jobject obj, jstring jmessage) {
 void Java_org_yuzu_yuzu_1emu_utils_Log_error(JNIEnv* env, jobject obj, jstring jmessage) {
-    LOG_ERROR(Frontend, "{}", GetJString(env, jmessage));
+    LOG_ERROR(Frontend, "{}", Common::Android::GetJString(env, jmessage));
 }
 }
 
 
 void Java_org_yuzu_yuzu_1emu_utils_Log_critical(JNIEnv* env, jobject obj, jstring jmessage) {
 void Java_org_yuzu_yuzu_1emu_utils_Log_critical(JNIEnv* env, jobject obj, jstring jmessage) {
-    LOG_CRITICAL(Frontend, "{}", GetJString(env, jmessage));
+    LOG_CRITICAL(Frontend, "{}", Common::Android::GetJString(env, jmessage));
 }
 }
 
 
 } // extern "C"
 } // extern "C"

+ 7 - 1
src/common/CMakeLists.txt

@@ -182,9 +182,15 @@ endif()
 
 
 if(ANDROID)
 if(ANDROID)
     target_sources(common
     target_sources(common
-        PRIVATE
+        PUBLIC
             fs/fs_android.cpp
             fs/fs_android.cpp
             fs/fs_android.h
             fs/fs_android.h
+            android/android_common.cpp
+            android/android_common.h
+            android/id_cache.cpp
+            android/id_cache.h
+            android/applets/software_keyboard.cpp
+            android/applets/software_keyboard.h
     )
     )
 endif()
 endif()
 
 

+ 14 - 9
src/android/app/src/main/jni/android_common/android_common.cpp → src/common/android/android_common.cpp

@@ -1,15 +1,17 @@
 // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 
-#include "jni/android_common/android_common.h"
+#include "android_common.h"
 
 
 #include <string>
 #include <string>
 #include <string_view>
 #include <string_view>
 
 
 #include <jni.h>
 #include <jni.h>
 
 
+#include "common/android/id_cache.h"
 #include "common/string_util.h"
 #include "common/string_util.h"
-#include "jni/id_cache.h"
+
+namespace Common::Android {
 
 
 std::string GetJString(JNIEnv* env, jstring jstr) {
 std::string GetJString(JNIEnv* env, jstring jstr) {
     if (!jstr) {
     if (!jstr) {
@@ -18,7 +20,8 @@ std::string GetJString(JNIEnv* env, jstring jstr) {
 
 
     const jchar* jchars = env->GetStringChars(jstr, nullptr);
     const jchar* jchars = env->GetStringChars(jstr, nullptr);
     const jsize length = env->GetStringLength(jstr);
     const jsize length = env->GetStringLength(jstr);
-    const std::u16string_view string_view(reinterpret_cast<const char16_t*>(jchars), length);
+    const std::u16string_view string_view(reinterpret_cast<const char16_t*>(jchars),
+                                          static_cast<u32>(length));
     const std::string converted_string = Common::UTF16ToUTF8(string_view);
     const std::string converted_string = Common::UTF16ToUTF8(string_view);
     env->ReleaseStringChars(jstr, jchars);
     env->ReleaseStringChars(jstr, jchars);
 
 
@@ -36,25 +39,27 @@ jstring ToJString(JNIEnv* env, std::u16string_view str) {
 }
 }
 
 
 double GetJDouble(JNIEnv* env, jobject jdouble) {
 double GetJDouble(JNIEnv* env, jobject jdouble) {
-    return env->GetDoubleField(jdouble, IDCache::GetDoubleValueField());
+    return env->GetDoubleField(jdouble, GetDoubleValueField());
 }
 }
 
 
 jobject ToJDouble(JNIEnv* env, double value) {
 jobject ToJDouble(JNIEnv* env, double value) {
-    return env->NewObject(IDCache::GetDoubleClass(), IDCache::GetDoubleConstructor(), value);
+    return env->NewObject(GetDoubleClass(), GetDoubleConstructor(), value);
 }
 }
 
 
 s32 GetJInteger(JNIEnv* env, jobject jinteger) {
 s32 GetJInteger(JNIEnv* env, jobject jinteger) {
-    return env->GetIntField(jinteger, IDCache::GetIntegerValueField());
+    return env->GetIntField(jinteger, GetIntegerValueField());
 }
 }
 
 
 jobject ToJInteger(JNIEnv* env, s32 value) {
 jobject ToJInteger(JNIEnv* env, s32 value) {
-    return env->NewObject(IDCache::GetIntegerClass(), IDCache::GetIntegerConstructor(), value);
+    return env->NewObject(GetIntegerClass(), GetIntegerConstructor(), value);
 }
 }
 
 
 bool GetJBoolean(JNIEnv* env, jobject jboolean) {
 bool GetJBoolean(JNIEnv* env, jobject jboolean) {
-    return env->GetBooleanField(jboolean, IDCache::GetBooleanValueField());
+    return env->GetBooleanField(jboolean, GetBooleanValueField());
 }
 }
 
 
 jobject ToJBoolean(JNIEnv* env, bool value) {
 jobject ToJBoolean(JNIEnv* env, bool value) {
-    return env->NewObject(IDCache::GetBooleanClass(), IDCache::GetBooleanConstructor(), value);
+    return env->NewObject(GetBooleanClass(), GetBooleanConstructor(), value);
 }
 }
+
+} // namespace Common::Android

+ 4 - 0
src/android/app/src/main/jni/android_common/android_common.h → src/common/android/android_common.h

@@ -8,6 +8,8 @@
 #include <jni.h>
 #include <jni.h>
 #include "common/common_types.h"
 #include "common/common_types.h"
 
 
+namespace Common::Android {
+
 std::string GetJString(JNIEnv* env, jstring jstr);
 std::string GetJString(JNIEnv* env, jstring jstr);
 jstring ToJString(JNIEnv* env, std::string_view str);
 jstring ToJString(JNIEnv* env, std::string_view str);
 jstring ToJString(JNIEnv* env, std::u16string_view str);
 jstring ToJString(JNIEnv* env, std::u16string_view str);
@@ -20,3 +22,5 @@ jobject ToJInteger(JNIEnv* env, s32 value);
 
 
 bool GetJBoolean(JNIEnv* env, jobject jboolean);
 bool GetJBoolean(JNIEnv* env, jobject jboolean);
 jobject ToJBoolean(JNIEnv* env, bool value);
 jobject ToJBoolean(JNIEnv* env, bool value);
+
+} // namespace Common::Android

+ 12 - 12
src/android/app/src/main/jni/applets/software_keyboard.cpp → src/common/android/applets/software_keyboard.cpp

@@ -6,12 +6,12 @@
 
 
 #include <jni.h>
 #include <jni.h>
 
 
+#include "common/android/android_common.h"
+#include "common/android/applets/software_keyboard.h"
+#include "common/android/id_cache.h"
 #include "common/logging/log.h"
 #include "common/logging/log.h"
 #include "common/string_util.h"
 #include "common/string_util.h"
 #include "core/core.h"
 #include "core/core.h"
-#include "jni/android_common/android_common.h"
-#include "jni/applets/software_keyboard.h"
-#include "jni/id_cache.h"
 
 
 static jclass s_software_keyboard_class;
 static jclass s_software_keyboard_class;
 static jclass s_keyboard_config_class;
 static jclass s_keyboard_config_class;
@@ -19,10 +19,10 @@ static jclass s_keyboard_data_class;
 static jmethodID s_swkbd_execute_normal;
 static jmethodID s_swkbd_execute_normal;
 static jmethodID s_swkbd_execute_inline;
 static jmethodID s_swkbd_execute_inline;
 
 
-namespace SoftwareKeyboard {
+namespace Common::Android::SoftwareKeyboard {
 
 
 static jobject ToJKeyboardParams(const Core::Frontend::KeyboardInitializeParameters& config) {
 static jobject ToJKeyboardParams(const Core::Frontend::KeyboardInitializeParameters& config) {
-    JNIEnv* env = IDCache::GetEnvForThread();
+    JNIEnv* env = GetEnvForThread();
     jobject object = env->AllocObject(s_keyboard_config_class);
     jobject object = env->AllocObject(s_keyboard_config_class);
 
 
     env->SetObjectField(object,
     env->SetObjectField(object,
@@ -78,7 +78,7 @@ static jobject ToJKeyboardParams(const Core::Frontend::KeyboardInitializeParamet
 }
 }
 
 
 AndroidKeyboard::ResultData AndroidKeyboard::ResultData::CreateFromFrontend(jobject object) {
 AndroidKeyboard::ResultData AndroidKeyboard::ResultData::CreateFromFrontend(jobject object) {
-    JNIEnv* env = IDCache::GetEnvForThread();
+    JNIEnv* env = GetEnvForThread();
     const jstring string = reinterpret_cast<jstring>(env->GetObjectField(
     const jstring string = reinterpret_cast<jstring>(env->GetObjectField(
         object, env->GetFieldID(s_keyboard_data_class, "text", "Ljava/lang/String;")));
         object, env->GetFieldID(s_keyboard_data_class, "text", "Ljava/lang/String;")));
     return ResultData{GetJString(env, string),
     return ResultData{GetJString(env, string),
@@ -141,7 +141,7 @@ void AndroidKeyboard::ShowNormalKeyboard() const {
 
 
     // Pivot to a new thread, as we cannot call GetEnvForThread() from a Fiber.
     // Pivot to a new thread, as we cannot call GetEnvForThread() from a Fiber.
     std::thread([&] {
     std::thread([&] {
-        data = ResultData::CreateFromFrontend(IDCache::GetEnvForThread()->CallStaticObjectMethod(
+        data = ResultData::CreateFromFrontend(GetEnvForThread()->CallStaticObjectMethod(
             s_software_keyboard_class, s_swkbd_execute_normal, ToJKeyboardParams(parameters)));
             s_software_keyboard_class, s_swkbd_execute_normal, ToJKeyboardParams(parameters)));
     }).join();
     }).join();
 
 
@@ -183,8 +183,8 @@ void AndroidKeyboard::ShowInlineKeyboard(
     // Pivot to a new thread, as we cannot call GetEnvForThread() from a Fiber.
     // Pivot to a new thread, as we cannot call GetEnvForThread() from a Fiber.
     m_is_inline_active = true;
     m_is_inline_active = true;
     std::thread([&] {
     std::thread([&] {
-        IDCache::GetEnvForThread()->CallStaticVoidMethod(
-            s_software_keyboard_class, s_swkbd_execute_inline, ToJKeyboardParams(parameters));
+        GetEnvForThread()->CallStaticVoidMethod(s_software_keyboard_class, s_swkbd_execute_inline,
+                                                ToJKeyboardParams(parameters));
     }).join();
     }).join();
 }
 }
 
 
@@ -220,7 +220,7 @@ void AndroidKeyboard::SubmitInlineKeyboardText(std::u16string submitted_text) {
     m_current_text += submitted_text;
     m_current_text += submitted_text;
 
 
     submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::ChangedString, m_current_text,
     submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::ChangedString, m_current_text,
-                           m_current_text.size());
+                           static_cast<int>(m_current_text.size()));
 }
 }
 
 
 void AndroidKeyboard::SubmitInlineKeyboardInput(int key_code) {
 void AndroidKeyboard::SubmitInlineKeyboardInput(int key_code) {
@@ -242,7 +242,7 @@ void AndroidKeyboard::SubmitInlineKeyboardInput(int key_code) {
     case KEYCODE_DEL:
     case KEYCODE_DEL:
         m_current_text.pop_back();
         m_current_text.pop_back();
         submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::ChangedString, m_current_text,
         submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::ChangedString, m_current_text,
-                               m_current_text.size());
+                               static_cast<int>(m_current_text.size()));
         break;
         break;
     }
     }
 }
 }
@@ -274,4 +274,4 @@ void CleanupJNI(JNIEnv* env) {
     env->DeleteGlobalRef(s_keyboard_data_class);
     env->DeleteGlobalRef(s_keyboard_data_class);
 }
 }
 
 
-} // namespace SoftwareKeyboard
+} // namespace Common::Android::SoftwareKeyboard

+ 2 - 2
src/android/app/src/main/jni/applets/software_keyboard.h → src/common/android/applets/software_keyboard.h

@@ -7,7 +7,7 @@
 
 
 #include "core/frontend/applets/software_keyboard.h"
 #include "core/frontend/applets/software_keyboard.h"
 
 
-namespace SoftwareKeyboard {
+namespace Common::Android::SoftwareKeyboard {
 
 
 class AndroidKeyboard final : public Core::Frontend::SoftwareKeyboardApplet {
 class AndroidKeyboard final : public Core::Frontend::SoftwareKeyboardApplet {
 public:
 public:
@@ -66,7 +66,7 @@ void InitJNI(JNIEnv* env);
 // Should be called in JNI_Unload
 // Should be called in JNI_Unload
 void CleanupJNI(JNIEnv* env);
 void CleanupJNI(JNIEnv* env);
 
 
-} // namespace SoftwareKeyboard
+} // namespace Common::Android::SoftwareKeyboard
 
 
 // Native function calls
 // Native function calls
 extern "C" {
 extern "C" {

+ 6 - 6
src/android/app/src/main/jni/id_cache.cpp → src/common/android/id_cache.cpp

@@ -3,10 +3,10 @@
 
 
 #include <jni.h>
 #include <jni.h>
 
 
+#include "applets/software_keyboard.h"
+#include "common/android/id_cache.h"
 #include "common/assert.h"
 #include "common/assert.h"
 #include "common/fs/fs_android.h"
 #include "common/fs/fs_android.h"
-#include "jni/applets/software_keyboard.h"
-#include "jni/id_cache.h"
 #include "video_core/rasterizer_interface.h"
 #include "video_core/rasterizer_interface.h"
 
 
 static JavaVM* s_java_vm;
 static JavaVM* s_java_vm;
@@ -67,7 +67,7 @@ static jfieldID s_boolean_value_field;
 
 
 static constexpr jint JNI_VERSION = JNI_VERSION_1_6;
 static constexpr jint JNI_VERSION = JNI_VERSION_1_6;
 
 
-namespace IDCache {
+namespace Common::Android {
 
 
 JNIEnv* GetEnvForThread() {
 JNIEnv* GetEnvForThread() {
     thread_local static struct OwnedEnv {
     thread_local static struct OwnedEnv {
@@ -276,8 +276,6 @@ jfieldID GetBooleanValueField() {
     return s_boolean_value_field;
     return s_boolean_value_field;
 }
 }
 
 
-} // namespace IDCache
-
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {
 #endif
 #endif
@@ -393,7 +391,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
     Common::FS::Android::RegisterCallbacks(env, s_native_library_class);
     Common::FS::Android::RegisterCallbacks(env, s_native_library_class);
 
 
     // Initialize applets
     // Initialize applets
-    SoftwareKeyboard::InitJNI(env);
+    Common::Android::SoftwareKeyboard::InitJNI(env);
 
 
     return JNI_VERSION;
     return JNI_VERSION;
 }
 }
@@ -426,3 +424,5 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) {
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif
+
+} // namespace Common::Android

+ 23 - 3
src/android/app/src/main/jni/id_cache.h → src/common/android/id_cache.h

@@ -3,20 +3,40 @@
 
 
 #pragma once
 #pragma once
 
 
+#include <future>
 #include <jni.h>
 #include <jni.h>
 
 
 #include "video_core/rasterizer_interface.h"
 #include "video_core/rasterizer_interface.h"
 
 
-namespace IDCache {
+namespace Common::Android {
 
 
 JNIEnv* GetEnvForThread();
 JNIEnv* GetEnvForThread();
+
+/**
+ * Starts a new thread to run JNI. Intended to be used when you must run JNI from a fiber.
+ * @tparam T Typename of the return value for the work param
+ * @param work Lambda that runs JNI code. This function will take care of attaching this thread to
+ * the JVM
+ * @return The result from the work lambda param
+ */
+template <typename T = void>
+T RunJNIOnFiber(const std::function<T(JNIEnv*)>& work) {
+    std::future<T> j_result = std::async(std::launch::async, [&] {
+        auto env = GetEnvForThread();
+        return work(env);
+    });
+    return j_result.get();
+}
+
 jclass GetNativeLibraryClass();
 jclass GetNativeLibraryClass();
+
 jclass GetDiskCacheProgressClass();
 jclass GetDiskCacheProgressClass();
 jclass GetDiskCacheLoadCallbackStageClass();
 jclass GetDiskCacheLoadCallbackStageClass();
 jclass GetGameDirClass();
 jclass GetGameDirClass();
 jmethodID GetGameDirConstructor();
 jmethodID GetGameDirConstructor();
-jmethodID GetExitEmulationActivity();
 jmethodID GetDiskCacheLoadProgress();
 jmethodID GetDiskCacheLoadProgress();
+
+jmethodID GetExitEmulationActivity();
 jmethodID GetOnEmulationStarted();
 jmethodID GetOnEmulationStarted();
 jmethodID GetOnEmulationStopped();
 jmethodID GetOnEmulationStopped();
 jmethodID GetOnProgramChanged();
 jmethodID GetOnProgramChanged();
@@ -65,4 +85,4 @@ jclass GetBooleanClass();
 jmethodID GetBooleanConstructor();
 jmethodID GetBooleanConstructor();
 jfieldID GetBooleanValueField();
 jfieldID GetBooleanValueField();
 
 
-} // namespace IDCache
+} // namespace Common::Android

+ 79 - 88
src/common/fs/fs_android.cpp

@@ -1,63 +1,38 @@
 // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 
+#include "common/android/android_common.h"
+#include "common/android/id_cache.h"
+#include "common/assert.h"
 #include "common/fs/fs_android.h"
 #include "common/fs/fs_android.h"
 #include "common/string_util.h"
 #include "common/string_util.h"
 
 
 namespace Common::FS::Android {
 namespace Common::FS::Android {
 
 
-JNIEnv* GetEnvForThread() {
-    thread_local static struct OwnedEnv {
-        OwnedEnv() {
-            status = g_jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
-            if (status == JNI_EDETACHED)
-                g_jvm->AttachCurrentThread(&env, nullptr);
-        }
-
-        ~OwnedEnv() {
-            if (status == JNI_EDETACHED)
-                g_jvm->DetachCurrentThread();
-        }
-
-        int status;
-        JNIEnv* env = nullptr;
-    } owned;
-    return owned.env;
-}
-
 void RegisterCallbacks(JNIEnv* env, jclass clazz) {
 void RegisterCallbacks(JNIEnv* env, jclass clazz) {
     env->GetJavaVM(&g_jvm);
     env->GetJavaVM(&g_jvm);
     native_library = clazz;
     native_library = clazz;
 
 
-#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature)                                \
-    F(JMethodID, JMethodName, Signature)
-#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature)                   \
-    F(JMethodID, JMethodName, Signature)
-#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature)               \
-    F(JMethodID, JMethodName, Signature)
-#define F(JMethodID, JMethodName, Signature)                                                       \
-    JMethodID = env->GetStaticMethodID(native_library, JMethodName, Signature);
-    ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
-    ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
-    ANDROID_STORAGE_FUNCTIONS(FS)
-#undef F
-#undef FS
-#undef FR
-#undef FH
+    s_get_parent_directory = env->GetStaticMethodID(native_library, "getParentDirectory",
+                                                    "(Ljava/lang/String;)Ljava/lang/String;");
+    s_get_filename = env->GetStaticMethodID(native_library, "getFilename",
+                                            "(Ljava/lang/String;)Ljava/lang/String;");
+    s_get_size = env->GetStaticMethodID(native_library, "getSize", "(Ljava/lang/String;)J");
+    s_is_directory = env->GetStaticMethodID(native_library, "isDirectory", "(Ljava/lang/String;)Z");
+    s_file_exists = env->GetStaticMethodID(native_library, "exists", "(Ljava/lang/String;)Z");
+    s_open_content_uri = env->GetStaticMethodID(native_library, "openContentUri",
+                                                "(Ljava/lang/String;Ljava/lang/String;)I");
 }
 }
 
 
 void UnRegisterCallbacks() {
 void UnRegisterCallbacks() {
-#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
-#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
-#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID)
-#define F(JMethodID) JMethodID = nullptr;
-    ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
-    ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
-    ANDROID_STORAGE_FUNCTIONS(FS)
-#undef F
-#undef FS
-#undef FR
-#undef FH
+    s_get_parent_directory = nullptr;
+    s_get_filename = nullptr;
+
+    s_get_size = nullptr;
+    s_is_directory = nullptr;
+    s_file_exists = nullptr;
+
+    s_open_content_uri = nullptr;
 }
 }
 
 
 bool IsContentUri(const std::string& path) {
 bool IsContentUri(const std::string& path) {
@@ -69,8 +44,8 @@ bool IsContentUri(const std::string& path) {
     return path.find(prefix) == 0;
     return path.find(prefix) == 0;
 }
 }
 
 
-int OpenContentUri(const std::string& filepath, OpenMode openmode) {
-    if (open_content_uri == nullptr)
+s32 OpenContentUri(const std::string& filepath, OpenMode openmode) {
+    if (s_open_content_uri == nullptr)
         return -1;
         return -1;
 
 
     const char* mode = "";
     const char* mode = "";
@@ -82,50 +57,66 @@ int OpenContentUri(const std::string& filepath, OpenMode openmode) {
         UNIMPLEMENTED();
         UNIMPLEMENTED();
         return -1;
         return -1;
     }
     }
-    auto env = GetEnvForThread();
-    jstring j_filepath = env->NewStringUTF(filepath.c_str());
-    jstring j_mode = env->NewStringUTF(mode);
-    return env->CallStaticIntMethod(native_library, open_content_uri, j_filepath, j_mode);
+    auto env = Common::Android::GetEnvForThread();
+    jstring j_filepath = Common::Android::ToJString(env, filepath);
+    jstring j_mode = Common::Android::ToJString(env, mode);
+    return env->CallStaticIntMethod(native_library, s_open_content_uri, j_filepath, j_mode);
+}
+
+u64 GetSize(const std::string& filepath) {
+    if (s_get_size == nullptr) {
+        return 0;
+    }
+    auto env = Common::Android::GetEnvForThread();
+    return static_cast<u64>(env->CallStaticLongMethod(
+        native_library, s_get_size,
+        Common::Android::ToJString(Common::Android::GetEnvForThread(), filepath)));
+}
+
+bool IsDirectory(const std::string& filepath) {
+    if (s_is_directory == nullptr) {
+        return 0;
+    }
+    auto env = Common::Android::GetEnvForThread();
+    return env->CallStaticBooleanMethod(
+        native_library, s_is_directory,
+        Common::Android::ToJString(Common::Android::GetEnvForThread(), filepath));
 }
 }
 
 
-#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature)                   \
-    F(FunctionName, ReturnValue, JMethodID, Caller)
-#define F(FunctionName, ReturnValue, JMethodID, Caller)                                            \
-    ReturnValue FunctionName(const std::string& filepath) {                                        \
-        if (JMethodID == nullptr) {                                                                \
-            return 0;                                                                              \
-        }                                                                                          \
-        auto env = GetEnvForThread();                                                              \
-        jstring j_filepath = env->NewStringUTF(filepath.c_str());                                  \
-        return env->Caller(native_library, JMethodID, j_filepath);                                 \
+bool Exists(const std::string& filepath) {
+    if (s_file_exists == nullptr) {
+        return 0;
     }
     }
-ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
-#undef F
-#undef FR
-
-#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature)                                \
-    F(FunctionName, JMethodID, Caller)
-#define F(FunctionName, JMethodID, Caller)                                                         \
-    std::string FunctionName(const std::string& filepath) {                                        \
-        if (JMethodID == nullptr) {                                                                \
-            return 0;                                                                              \
-        }                                                                                          \
-        auto env = GetEnvForThread();                                                              \
-        jstring j_filepath = env->NewStringUTF(filepath.c_str());                                  \
-        jstring j_return =                                                                         \
-            static_cast<jstring>(env->Caller(native_library, JMethodID, j_filepath));              \
-        if (!j_return) {                                                                           \
-            return {};                                                                             \
-        }                                                                                          \
-        const jchar* jchars = env->GetStringChars(j_return, nullptr);                              \
-        const jsize length = env->GetStringLength(j_return);                                       \
-        const std::u16string_view string_view(reinterpret_cast<const char16_t*>(jchars), length);  \
-        const std::string converted_string = Common::UTF16ToUTF8(string_view);                     \
-        env->ReleaseStringChars(j_return, jchars);                                                 \
-        return converted_string;                                                                   \
+    auto env = Common::Android::GetEnvForThread();
+    return env->CallStaticBooleanMethod(
+        native_library, s_file_exists,
+        Common::Android::ToJString(Common::Android::GetEnvForThread(), filepath));
+}
+
+std::string GetParentDirectory(const std::string& filepath) {
+    if (s_get_parent_directory == nullptr) {
+        return 0;
     }
     }
-ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
-#undef F
-#undef FH
+    auto env = Common::Android::GetEnvForThread();
+    jstring j_return = static_cast<jstring>(env->CallStaticObjectMethod(
+        native_library, s_get_parent_directory, Common::Android::ToJString(env, filepath)));
+    if (!j_return) {
+        return {};
+    }
+    return Common::Android::GetJString(env, j_return);
+}
+
+std::string GetFilename(const std::string& filepath) {
+    if (s_get_filename == nullptr) {
+        return 0;
+    }
+    auto env = Common::Android::GetEnvForThread();
+    jstring j_return = static_cast<jstring>(env->CallStaticObjectMethod(
+        native_library, s_get_filename, Common::Android::ToJString(env, filepath)));
+    if (!j_return) {
+        return {};
+    }
+    return Common::Android::GetJString(env, j_return);
+}
 
 
 } // namespace Common::FS::Android
 } // namespace Common::FS::Android

+ 12 - 46
src/common/fs/fs_android.h

@@ -7,38 +7,17 @@
 #include <vector>
 #include <vector>
 #include <jni.h>
 #include <jni.h>
 
 
-#define ANDROID_STORAGE_FUNCTIONS(V)                                                               \
-    V(OpenContentUri, int, (const std::string& filepath, OpenMode openmode), open_content_uri,     \
-      "openContentUri", "(Ljava/lang/String;Ljava/lang/String;)I")
-
-#define ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(V)                                                 \
-    V(GetSize, std::uint64_t, get_size, CallStaticLongMethod, "getSize", "(Ljava/lang/String;)J")  \
-    V(IsDirectory, bool, is_directory, CallStaticBooleanMethod, "isDirectory",                     \
-      "(Ljava/lang/String;)Z")                                                                     \
-    V(Exists, bool, file_exists, CallStaticBooleanMethod, "exists", "(Ljava/lang/String;)Z")
-
-#define ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(V)                                                    \
-    V(GetParentDirectory, get_parent_directory, CallStaticObjectMethod, "getParentDirectory",      \
-      "(Ljava/lang/String;)Ljava/lang/String;")                                                    \
-    V(GetFilename, get_filename, CallStaticObjectMethod, "getFilename",                            \
-      "(Ljava/lang/String;)Ljava/lang/String;")
-
 namespace Common::FS::Android {
 namespace Common::FS::Android {
 
 
 static JavaVM* g_jvm = nullptr;
 static JavaVM* g_jvm = nullptr;
 static jclass native_library = nullptr;
 static jclass native_library = nullptr;
 
 
-#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
-#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
-#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID)
-#define F(JMethodID) static jmethodID JMethodID = nullptr;
-ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
-ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
-ANDROID_STORAGE_FUNCTIONS(FS)
-#undef F
-#undef FS
-#undef FR
-#undef FH
+static jmethodID s_get_parent_directory;
+static jmethodID s_get_filename;
+static jmethodID s_get_size;
+static jmethodID s_is_directory;
+static jmethodID s_file_exists;
+static jmethodID s_open_content_uri;
 
 
 enum class OpenMode {
 enum class OpenMode {
     Read,
     Read,
@@ -57,24 +36,11 @@ void UnRegisterCallbacks();
 
 
 bool IsContentUri(const std::string& path);
 bool IsContentUri(const std::string& path);
 
 
-#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature)               \
-    F(FunctionName, Parameters, ReturnValue)
-#define F(FunctionName, Parameters, ReturnValue) ReturnValue FunctionName Parameters;
-ANDROID_STORAGE_FUNCTIONS(FS)
-#undef F
-#undef FS
-
-#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature)                   \
-    F(FunctionName, ReturnValue)
-#define F(FunctionName, ReturnValue) ReturnValue FunctionName(const std::string& filepath);
-ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
-#undef F
-#undef FR
-
-#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(FunctionName)
-#define F(FunctionName) std::string FunctionName(const std::string& filepath);
-ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
-#undef F
-#undef FH
+int OpenContentUri(const std::string& filepath, OpenMode openmode);
+std::uint64_t GetSize(const std::string& filepath);
+bool IsDirectory(const std::string& filepath);
+bool Exists(const std::string& filepath);
+std::string GetParentDirectory(const std::string& filepath);
+std::string GetFilename(const std::string& filepath);
 
 
 } // namespace Common::FS::Android
 } // namespace Common::FS::Android