summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorliamwhite <liamwhite@users.noreply.github.com>2024-02-09 17:49:25 +0100
committerGitHub <noreply@github.com>2024-02-09 17:49:25 +0100
commit7ec7ff0f303504950e4270e91076a33efd0ceb17 (patch)
tree1e8346f775550eefd491aa8280412d86000dd637
parentMerge pull request #12927 from german77/cheat-pause (diff)
parentandroid: Run OnEmulationStarted frontend callback in another thread (diff)
downloadyuzu-7ec7ff0f303504950e4270e91076a33efd0ceb17.tar
yuzu-7ec7ff0f303504950e4270e91076a33efd0ceb17.tar.gz
yuzu-7ec7ff0f303504950e4270e91076a33efd0ceb17.tar.bz2
yuzu-7ec7ff0f303504950e4270e91076a33efd0ceb17.tar.lz
yuzu-7ec7ff0f303504950e4270e91076a33efd0ceb17.tar.xz
yuzu-7ec7ff0f303504950e4270e91076a33efd0ceb17.tar.zst
yuzu-7ec7ff0f303504950e4270e91076a33efd0ceb17.zip
-rw-r--r--src/android/app/src/main/jni/CMakeLists.txt6
-rw-r--r--src/android/app/src/main/jni/emu_window/emu_window.cpp4
-rw-r--r--src/android/app/src/main/jni/game_metadata.cpp22
-rw-r--r--src/android/app/src/main/jni/native.cpp125
-rw-r--r--src/android/app/src/main/jni/native.h6
-rw-r--r--src/android/app/src/main/jni/native_config.cpp121
-rw-r--r--src/android/app/src/main/jni/native_log.cpp13
-rw-r--r--src/common/CMakeLists.txt8
-rw-r--r--src/common/android/android_common.cpp (renamed from src/android/app/src/main/jni/android_common/android_common.cpp)23
-rw-r--r--src/common/android/android_common.h (renamed from src/android/app/src/main/jni/android_common/android_common.h)4
-rw-r--r--src/common/android/applets/software_keyboard.cpp (renamed from src/android/app/src/main/jni/applets/software_keyboard.cpp)24
-rw-r--r--src/common/android/applets/software_keyboard.h (renamed from src/android/app/src/main/jni/applets/software_keyboard.h)4
-rw-r--r--src/common/android/id_cache.cpp (renamed from src/android/app/src/main/jni/id_cache.cpp)12
-rw-r--r--src/common/android/id_cache.h (renamed from src/android/app/src/main/jni/id_cache.h)26
-rw-r--r--src/common/fs/fs_android.cpp167
-rw-r--r--src/common/fs/fs_android.h58
16 files changed, 318 insertions, 305 deletions
diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt
index abc6055ab..20b319c12 100644
--- a/src/android/app/src/main/jni/CMakeLists.txt
+++ b/src/android/app/src/main/jni/CMakeLists.txt
@@ -2,14 +2,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
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.h
- id_cache.cpp
- id_cache.h
native.cpp
native.h
native_config.cpp
diff --git a/src/android/app/src/main/jni/emu_window/emu_window.cpp b/src/android/app/src/main/jni/emu_window/emu_window.cpp
index c4f631924..c927cddda 100644
--- a/src/android/app/src/main/jni/emu_window/emu_window.cpp
+++ b/src/android/app/src/main/jni/emu_window/emu_window.cpp
@@ -3,6 +3,7 @@
#include <android/native_window_jni.h>
+#include "common/android/id_cache.h"
#include "common/logging/log.h"
#include "input_common/drivers/touch_screen.h"
#include "input_common/drivers/virtual_amiibo.h"
@@ -60,7 +61,8 @@ void EmuWindow_Android::OnRemoveNfcTag() {
void EmuWindow_Android::OnFrameDisplayed() {
if (!m_first_frame) {
- EmulationSession::GetInstance().OnEmulationStarted();
+ Common::Android::RunJNIOnFiber<void>(
+ [&](JNIEnv* env) { EmulationSession::GetInstance().OnEmulationStarted(); });
m_first_frame = true;
}
}
diff --git a/src/android/app/src/main/jni/game_metadata.cpp b/src/android/app/src/main/jni/game_metadata.cpp
index 8f0da1413..c33763b47 100644
--- a/src/android/app/src/main/jni/game_metadata.cpp
+++ b/src/android/app/src/main/jni/game_metadata.cpp
@@ -1,13 +1,12 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "common/android/android_common.h"
#include "core/core.h"
#include "core/file_sys/fs_filesystem.h"
#include "core/file_sys/patch_manager.h"
#include "core/loader/loader.h"
#include "core/loader/nro.h"
-#include "jni.h"
-#include "jni/android_common/android_common.h"
#include "native.h"
struct RomMetadata {
@@ -79,7 +78,7 @@ extern "C" {
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobject obj,
jstring jpath) {
const auto file = EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
- GetJString(env, jpath), FileSys::OpenMode::Read);
+ Common::Android::GetJString(env, jpath), FileSys::OpenMode::Read);
if (!file) {
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 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 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 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 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,
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()));
env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon),
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,
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) {
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 654510129..4acc60956 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -20,6 +20,8 @@
#include <frontend_common/content_manager.h>
#include <jni.h>
+#include "common/android/android_common.h"
+#include "common/android/id_cache.h"
#include "common/detached_tasks.h"
#include "common/dynamic_library.h"
#include "common/fs/path_util.h"
@@ -57,8 +59,6 @@
#include "hid_core/frontend/emulated_controller.h"
#include "hid_core/hid_core.h"
#include "hid_core/hid_types.h"
-#include "jni/android_common/android_common.h"
-#include "jni/id_cache.h"
#include "jni/native.h"
#include "video_core/renderer_base.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);
// 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_system.SetShuttingDown(false);
m_system.ApplySettings();
@@ -411,37 +411,39 @@ void EmulationSession::OnGamepadDisconnectEvent([[maybe_unused]] int index) {
controller->Disconnect();
}
-SoftwareKeyboard::AndroidKeyboard* EmulationSession::SoftwareKeyboard() {
+Common::Android::SoftwareKeyboard::AndroidKeyboard* EmulationSession::SoftwareKeyboard() {
return m_software_keyboard;
}
void EmulationSession::LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress,
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));
}
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) {
- 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) {
- 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));
}
u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) {
- auto program_id_string = GetJString(env, jprogramId);
+ auto program_id_string = Common::Android::GetJString(env, jprogramId);
try {
return std::stoull(program_id_string);
} 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,
[[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,
@@ -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;");
const auto callback = [env, jcallback, jlambdaInvokeMethod](size_t max, size_t progress) {
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>(
ContentManager::InstallNSP(EmulationSession::GetInstance().System(),
*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,
jstring jprogramId,
jstring jupdatePath) {
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>(
EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
updatePath, FileSys::OpenMode::Read));
@@ -538,8 +541,10 @@ void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeGpuDriver(JNIEnv* e
jstring custom_driver_name,
jstring file_redirect_dir) {
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() {
@@ -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) {
const char* file_redirect_dir_{};
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(),
nullptr, nullptr, file_redirect_dir_, nullptr);
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),
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;
}
@@ -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) {
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) {
- 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) {
@@ -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,
jint j_program_index,
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{
RunEmulation(path, j_program_index, j_frontend_initiated)};
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,
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);
}
@@ -815,16 +822,16 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getAppletLaunchPath(JNIEnv* env, j
auto bis_system =
EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
if (!bis_system) {
- return ToJString(env, "");
+ return Common::Android::ToJString(env, "");
}
auto applet_nca =
bis_system->GetEntry(static_cast<u64>(jid), FileSys::ContentRecordType::Program);
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,
@@ -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,
jstring jpath,
jstring jprogramId) {
- const auto path = GetJString(env, jpath);
+ const auto path = Common::Android::GetJString(env, jpath);
const auto vFile =
Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path);
if (vFile == nullptr) {
@@ -875,14 +882,15 @@ jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env
auto patches = pm.GetPatches(update_raw);
jobjectArray jpatchArray =
- env->NewObjectArray(patches.size(), IDCache::GetPatchClass(), nullptr);
+ env->NewObjectArray(patches.size(), Common::Android::GetPatchClass(), nullptr);
int i = 0;
for (const auto& patch : patches) {
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);
++i;
}
@@ -906,7 +914,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_removeMod(JNIEnv* env, jobject jobj,
jstring jname) {
auto program_id = EmulationSession::GetProgramId(env, jprogramId);
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,
@@ -917,17 +925,18 @@ jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyInstalledContents(JNIEn
jlambdaClass, "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
const auto callback = [env, jcallback, jlambdaInvokeMethod](size_t max, size_t progress) {
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();
std::vector<std::string> result = ContentManager::VerifyInstalledContents(
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) {
- env->SetObjectArrayElement(jresult, i, ToJString(env, result[i]));
+ env->SetObjectArrayElement(jresult, i, Common::Android::ToJString(env, result[i]));
}
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;");
const auto callback = [env, jcallback, jlambdaInvokeMethod](size_t max, size_t progress) {
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();
- 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 jprogramId) {
auto program_id = EmulationSession::GetProgramId(env, jprogramId);
if (program_id == 0) {
- return ToJString(env, "");
+ return Common::Android::ToJString(env, "");
}
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(
{}, vfsNandDir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
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,
@@ -981,12 +991,13 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getDefaultProfileSaveDataRoot(JNIE
const auto user_save_data_root =
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,
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) {
diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h
index e49d4e015..47936e305 100644
--- a/src/android/app/src/main/jni/native.h
+++ b/src/android/app/src/main/jni/native.h
@@ -2,13 +2,13 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <android/native_window_jni.h>
+#include "common/android/applets/software_keyboard.h"
#include "common/detached_tasks.h"
#include "core/core.h"
#include "core/file_sys/registered_cache.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/perf_stats.h"
#include "frontend_common/content_manager.h"
-#include "jni/applets/software_keyboard.h"
#include "jni/emu_window/emu_window.h"
#include "video_core/rasterizer_interface.h"
@@ -54,7 +54,7 @@ public:
void SetDeviceType([[maybe_unused]] int index, int type);
void OnGamepadConnectEvent([[maybe_unused]] int index);
void OnGamepadDisconnectEvent([[maybe_unused]] int index);
- SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard();
+ Common::Android::SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard();
static void OnEmulationStarted();
@@ -79,7 +79,7 @@ private:
Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
std::atomic<bool> m_is_running = 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;
int m_applet_id{1};
diff --git a/src/android/app/src/main/jni/native_config.cpp b/src/android/app/src/main/jni/native_config.cpp
index c6c3343dc..8ae10fbc7 100644
--- a/src/android/app/src/main/jni/native_config.cpp
+++ b/src/android/app/src/main/jni/native_config.cpp
@@ -8,11 +8,11 @@
#include "android_config.h"
#include "android_settings.h"
+#include "common/android/android_common.h"
+#include "common/android/id_cache.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "frontend_common/config.h"
-#include "jni/android_common/android_common.h"
-#include "jni/id_cache.h"
#include "native.h"
std::unique_ptr<AndroidConfig> global_config;
@@ -20,7 +20,7 @@ std::unique_ptr<AndroidConfig> per_game_config;
template <typename T>
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];
if (basic_setting != 0) {
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 jfileName) {
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);
per_game_config =
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) {
auto setting = getSetting<std::string>(env, jkey);
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,
@@ -198,7 +198,7 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setString(JNIEnv* env, jobject o
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,
@@ -214,13 +214,13 @@ jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getPairedSettingKey(JNIEnv* e
jstring jkey) {
auto setting = getSetting<std::string>(env, jkey);
if (setting == nullptr) {
- return ToJString(env, "");
+ return Common::Android::ToJString(env, "");
}
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,
@@ -262,21 +262,21 @@ jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getDefaultToString(JNIEnv* en
jstring jkey) {
auto setting = getSetting<std::string>(env, jkey);
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) {
- jclass gameDirClass = IDCache::GetGameDirClass();
- jmethodID gameDirConstructor = IDCache::GetGameDirConstructor();
+ jclass gameDirClass = Common::Android::GetGameDirClass();
+ jmethodID gameDirConstructor = Common::Android::GetGameDirConstructor();
jobjectArray jgameDirArray =
env->NewObjectArray(AndroidSettings::values.game_dirs.size(), gameDirClass, nullptr);
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);
}
return jgameDirArray;
@@ -292,14 +292,14 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setGameDirs(JNIEnv* env, jobject
}
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 deepScanBooleanField = env->GetFieldID(gameDirClass, "deepScan", "Z");
for (int i = 0; i < size; ++i) {
dir = env->GetObjectArrayElement(gameDirs, i);
jstring juriString = static_cast<jstring>(env->GetObjectField(dir, uriStringField));
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::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,
jobject gameDir) {
- jclass gameDirClass = IDCache::GetGameDirClass();
+ jclass gameDirClass = Common::Android::GetGameDirClass();
jfieldID uriStringField = env->GetFieldID(gameDirClass, "uriString", "Ljava/lang/String;");
jfieldID deepScanBooleanField = env->GetFieldID(gameDirClass, "deepScan", "Z");
jstring juriString = static_cast<jstring>(env->GetObjectField(gameDir, uriStringField));
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::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& disabledAddons = Settings::values.disabled_addons[program_id];
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) {
- env->SetObjectArrayElement(jdisabledAddonsArray, i, ToJString(env, disabledAddons[i]));
+ env->SetObjectArrayElement(jdisabledAddonsArray, i,
+ Common::Android::ToJString(env, disabledAddons[i]));
}
return jdisabledAddonsArray;
}
@@ -339,7 +341,7 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setDisabledAddons(JNIEnv* env, j
const int size = env->GetArrayLength(jdisabledAddons);
for (int i = 0; i < size; ++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;
}
@@ -348,26 +350,27 @@ jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getOverlayControlData(JN
jobject obj) {
jobjectArray joverlayControlDataArray =
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) {
const auto& control_data = AndroidSettings::values.overlay_control_data[i];
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 =
- 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 =
- 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);
}
return joverlayControlDataArray;
@@ -384,33 +387,41 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setOverlayControlData(
for (int i = 0; i < size; ++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(
- joverlayControlData, IDCache::GetOverlayControlDataEnabledField()));
+ joverlayControlData, Common::Android::GetOverlayControlDataEnabledField()));
jobject jlandscapePosition = env->GetObjectField(
- joverlayControlData, IDCache::GetOverlayControlDataLandscapePositionField());
+ joverlayControlData, Common::Android::GetOverlayControlDataLandscapePositionField());
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(
- joverlayControlData, IDCache::GetOverlayControlDataPortraitPositionField());
+ joverlayControlData, Common::Android::GetOverlayControlDataPortraitPositionField());
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(
- joverlayControlData, IDCache::GetOverlayControlDataFoldablePositionField());
+ joverlayControlData, Common::Android::GetOverlayControlDataFoldablePositionField());
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{
- GetJString(env, jidString), enabled, landscape_position, portrait_position,
- foldable_position});
+ Common::Android::GetJString(env, jidString), enabled, landscape_position,
+ portrait_position, foldable_position});
}
}
diff --git a/src/android/app/src/main/jni/native_log.cpp b/src/android/app/src/main/jni/native_log.cpp
index 33d691dc8..95dd1f057 100644
--- a/src/android/app/src/main/jni/native_log.cpp
+++ b/src/android/app/src/main/jni/native_log.cpp
@@ -1,31 +1,30 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include <common/android/android_common.h>
#include <common/logging/log.h>
#include <jni.h>
-#include "android_common/android_common.h"
-
extern "C" {
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) {
- 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) {
- 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) {
- 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) {
- LOG_CRITICAL(Frontend, "{}", GetJString(env, jmessage));
+ LOG_CRITICAL(Frontend, "{}", Common::Android::GetJString(env, jmessage));
}
} // extern "C"
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index c19af2ab8..779be211e 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -182,9 +182,15 @@ endif()
if(ANDROID)
target_sources(common
- PRIVATE
+ PUBLIC
fs/fs_android.cpp
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()
diff --git a/src/android/app/src/main/jni/android_common/android_common.cpp b/src/common/android/android_common.cpp
index 7018a52af..e79005658 100644
--- a/src/android/app/src/main/jni/android_common/android_common.cpp
+++ b/src/common/android/android_common.cpp
@@ -1,15 +1,17 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-#include "jni/android_common/android_common.h"
+#include "android_common.h"
#include <string>
#include <string_view>
#include <jni.h>
+#include "common/android/id_cache.h"
#include "common/string_util.h"
-#include "jni/id_cache.h"
+
+namespace Common::Android {
std::string GetJString(JNIEnv* env, jstring jstr) {
if (!jstr) {
@@ -18,7 +20,8 @@ std::string GetJString(JNIEnv* env, jstring jstr) {
const jchar* jchars = env->GetStringChars(jstr, nullptr);
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);
env->ReleaseStringChars(jstr, jchars);
@@ -36,25 +39,27 @@ jstring ToJString(JNIEnv* env, std::u16string_view str) {
}
double GetJDouble(JNIEnv* env, jobject jdouble) {
- return env->GetDoubleField(jdouble, IDCache::GetDoubleValueField());
+ return env->GetDoubleField(jdouble, GetDoubleValueField());
}
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) {
- return env->GetIntField(jinteger, IDCache::GetIntegerValueField());
+ return env->GetIntField(jinteger, GetIntegerValueField());
}
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) {
- return env->GetBooleanField(jboolean, IDCache::GetBooleanValueField());
+ return env->GetBooleanField(jboolean, GetBooleanValueField());
}
jobject ToJBoolean(JNIEnv* env, bool value) {
- return env->NewObject(IDCache::GetBooleanClass(), IDCache::GetBooleanConstructor(), value);
+ return env->NewObject(GetBooleanClass(), GetBooleanConstructor(), value);
}
+
+} // namespace Common::Android
diff --git a/src/android/app/src/main/jni/android_common/android_common.h b/src/common/android/android_common.h
index 29a338c0a..d0ccb4ec2 100644
--- a/src/android/app/src/main/jni/android_common/android_common.h
+++ b/src/common/android/android_common.h
@@ -8,6 +8,8 @@
#include <jni.h>
#include "common/common_types.h"
+namespace Common::Android {
+
std::string GetJString(JNIEnv* env, jstring jstr);
jstring ToJString(JNIEnv* env, std::string_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);
jobject ToJBoolean(JNIEnv* env, bool value);
+
+} // namespace Common::Android
diff --git a/src/android/app/src/main/jni/applets/software_keyboard.cpp b/src/common/android/applets/software_keyboard.cpp
index 9943483e8..477e62b16 100644
--- a/src/android/app/src/main/jni/applets/software_keyboard.cpp
+++ b/src/common/android/applets/software_keyboard.cpp
@@ -6,12 +6,12 @@
#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/string_util.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_keyboard_config_class;
@@ -19,10 +19,10 @@ static jclass s_keyboard_data_class;
static jmethodID s_swkbd_execute_normal;
static jmethodID s_swkbd_execute_inline;
-namespace SoftwareKeyboard {
+namespace Common::Android::SoftwareKeyboard {
static jobject ToJKeyboardParams(const Core::Frontend::KeyboardInitializeParameters& config) {
- JNIEnv* env = IDCache::GetEnvForThread();
+ JNIEnv* env = GetEnvForThread();
jobject object = env->AllocObject(s_keyboard_config_class);
env->SetObjectField(object,
@@ -78,7 +78,7 @@ static jobject ToJKeyboardParams(const Core::Frontend::KeyboardInitializeParamet
}
AndroidKeyboard::ResultData AndroidKeyboard::ResultData::CreateFromFrontend(jobject object) {
- JNIEnv* env = IDCache::GetEnvForThread();
+ JNIEnv* env = GetEnvForThread();
const jstring string = reinterpret_cast<jstring>(env->GetObjectField(
object, env->GetFieldID(s_keyboard_data_class, "text", "Ljava/lang/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.
std::thread([&] {
- data = ResultData::CreateFromFrontend(IDCache::GetEnvForThread()->CallStaticObjectMethod(
+ data = ResultData::CreateFromFrontend(GetEnvForThread()->CallStaticObjectMethod(
s_software_keyboard_class, s_swkbd_execute_normal, ToJKeyboardParams(parameters)));
}).join();
@@ -183,8 +183,8 @@ void AndroidKeyboard::ShowInlineKeyboard(
// Pivot to a new thread, as we cannot call GetEnvForThread() from a Fiber.
m_is_inline_active = true;
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();
}
@@ -220,7 +220,7 @@ void AndroidKeyboard::SubmitInlineKeyboardText(std::u16string submitted_text) {
m_current_text += submitted_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) {
@@ -242,7 +242,7 @@ void AndroidKeyboard::SubmitInlineKeyboardInput(int key_code) {
case KEYCODE_DEL:
m_current_text.pop_back();
submit_inline_callback(Service::AM::Frontend::SwkbdReplyType::ChangedString, m_current_text,
- m_current_text.size());
+ static_cast<int>(m_current_text.size()));
break;
}
}
@@ -274,4 +274,4 @@ void CleanupJNI(JNIEnv* env) {
env->DeleteGlobalRef(s_keyboard_data_class);
}
-} // namespace SoftwareKeyboard
+} // namespace Common::Android::SoftwareKeyboard
diff --git a/src/android/app/src/main/jni/applets/software_keyboard.h b/src/common/android/applets/software_keyboard.h
index 2affc01f6..9fd09d27c 100644
--- a/src/android/app/src/main/jni/applets/software_keyboard.h
+++ b/src/common/android/applets/software_keyboard.h
@@ -7,7 +7,7 @@
#include "core/frontend/applets/software_keyboard.h"
-namespace SoftwareKeyboard {
+namespace Common::Android::SoftwareKeyboard {
class AndroidKeyboard final : public Core::Frontend::SoftwareKeyboardApplet {
public:
@@ -66,7 +66,7 @@ void InitJNI(JNIEnv* env);
// Should be called in JNI_Unload
void CleanupJNI(JNIEnv* env);
-} // namespace SoftwareKeyboard
+} // namespace Common::Android::SoftwareKeyboard
// Native function calls
extern "C" {
diff --git a/src/android/app/src/main/jni/id_cache.cpp b/src/common/android/id_cache.cpp
index f30100bd8..f39262db9 100644
--- a/src/android/app/src/main/jni/id_cache.cpp
+++ b/src/common/android/id_cache.cpp
@@ -3,10 +3,10 @@
#include <jni.h>
+#include "applets/software_keyboard.h"
+#include "common/android/id_cache.h"
#include "common/assert.h"
#include "common/fs/fs_android.h"
-#include "jni/applets/software_keyboard.h"
-#include "jni/id_cache.h"
#include "video_core/rasterizer_interface.h"
static JavaVM* s_java_vm;
@@ -67,7 +67,7 @@ static jfieldID s_boolean_value_field;
static constexpr jint JNI_VERSION = JNI_VERSION_1_6;
-namespace IDCache {
+namespace Common::Android {
JNIEnv* GetEnvForThread() {
thread_local static struct OwnedEnv {
@@ -276,8 +276,6 @@ jfieldID GetBooleanValueField() {
return s_boolean_value_field;
}
-} // namespace IDCache
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -393,7 +391,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
Common::FS::Android::RegisterCallbacks(env, s_native_library_class);
// Initialize applets
- SoftwareKeyboard::InitJNI(env);
+ Common::Android::SoftwareKeyboard::InitJNI(env);
return JNI_VERSION;
}
@@ -426,3 +424,5 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) {
#ifdef __cplusplus
}
#endif
+
+} // namespace Common::Android
diff --git a/src/android/app/src/main/jni/id_cache.h b/src/common/android/id_cache.h
index 00e48afc0..47802f96c 100644
--- a/src/android/app/src/main/jni/id_cache.h
+++ b/src/common/android/id_cache.h
@@ -3,20 +3,40 @@
#pragma once
+#include <future>
#include <jni.h>
#include "video_core/rasterizer_interface.h"
-namespace IDCache {
+namespace Common::Android {
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 GetDiskCacheProgressClass();
jclass GetDiskCacheLoadCallbackStageClass();
jclass GetGameDirClass();
jmethodID GetGameDirConstructor();
-jmethodID GetExitEmulationActivity();
jmethodID GetDiskCacheLoadProgress();
+
+jmethodID GetExitEmulationActivity();
jmethodID GetOnEmulationStarted();
jmethodID GetOnEmulationStopped();
jmethodID GetOnProgramChanged();
@@ -65,4 +85,4 @@ jclass GetBooleanClass();
jmethodID GetBooleanConstructor();
jfieldID GetBooleanValueField();
-} // namespace IDCache
+} // namespace Common::Android
diff --git a/src/common/fs/fs_android.cpp b/src/common/fs/fs_android.cpp
index 1dd826a4a..9a8053222 100644
--- a/src/common/fs/fs_android.cpp
+++ b/src/common/fs/fs_android.cpp
@@ -1,63 +1,38 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// 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/string_util.h"
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) {
env->GetJavaVM(&g_jvm);
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() {
-#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) {
@@ -69,8 +44,8 @@ bool IsContentUri(const std::string& path) {
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;
const char* mode = "";
@@ -82,50 +57,66 @@ int OpenContentUri(const std::string& filepath, OpenMode openmode) {
UNIMPLEMENTED();
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
diff --git a/src/common/fs/fs_android.h b/src/common/fs/fs_android.h
index 2c9234313..b33f4beb8 100644
--- a/src/common/fs/fs_android.h
+++ b/src/common/fs/fs_android.h
@@ -7,38 +7,17 @@
#include <vector>
#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 {
static JavaVM* g_jvm = 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 {
Read,
@@ -57,24 +36,11 @@ void UnRegisterCallbacks();
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