mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-12-19 20:11:00 +01:00
Merge pull request #12920 from t895/jni-common
android: Move JNI setup and helpers to common
This commit is contained in:
commit
7ec7ff0f30
16 changed files with 316 additions and 303 deletions
|
@ -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,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
JNIEnv* env = Common::Android::GetEnvForThread();
|
||||||
env->CallStaticVoidMethod(IDCache::GetDiskCacheProgressClass(),
|
env->CallStaticVoidMethod(Common::Android::GetDiskCacheProgressClass(),
|
||||||
IDCache::GetDiskCacheLoadProgress(), static_cast<jint>(stage),
|
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();
|
JNIEnv* env = Common::Android::GetEnvForThread();
|
||||||
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnEmulationStarted());
|
env->CallStaticVoidMethod(Common::Android::GetNativeLibraryClass(),
|
||||||
|
Common::Android::GetOnEmulationStarted());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) {
|
void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) {
|
||||||
JNIEnv* env = IDCache::GetEnvForThread();
|
JNIEnv* env = Common::Android::GetEnvForThread();
|
||||||
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnEmulationStopped(),
|
env->CallStaticVoidMethod(Common::Android::GetNativeLibraryClass(),
|
||||||
static_cast<jint>(result));
|
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();
|
JNIEnv* env = Common::Android::GetEnvForThread();
|
||||||
env->CallStaticVoidMethod(IDCache::GetNativeLibraryClass(), IDCache::GetOnProgramChanged(),
|
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));
|
Common::Android::ToJDouble(env, max),
|
||||||
return GetJBoolean(env, jwasCancelled);
|
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),
|
Common::Android::GetJString(env, hook_lib_dir),
|
||||||
GetJString(env, custom_driver_name), GetJString(env, file_redirect_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 =
|
jobjectArray j_driver_info = env->NewObjectArray(
|
||||||
env->NewObjectArray(2, IDCache::GetStringClass(), ToJString(env, version_string));
|
2, Common::Android::GetStringClass(), Common::Android::ToJString(env, version_string));
|
||||||
env->SetObjectArrayElement(j_driver_info, 1, ToJString(env, device.GetDriverName()));
|
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,
|
return Common::Android::ToJString(
|
||||||
EmulationSession::GetInstance().System().GPU().Renderer().GetDeviceVendor());
|
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(),
|
env->CallStaticVoidMethod(Common::Android::GetNativeLibraryClass(),
|
||||||
IDCache::GetExitEmulationActivity(), static_cast<int>(result));
|
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,
|
Common::Android::GetPatchClass(), Common::Android::GetPatchConstructor(), patch.enabled,
|
||||||
ToJString(env, patch.name), ToJString(env, patch.version),
|
Common::Android::ToJString(env, patch.name),
|
||||||
static_cast<jint>(patch.type), ToJString(env, std::to_string(patch.program_id)),
|
Common::Android::ToJString(env, patch.version), static_cast<jint>(patch.type),
|
||||||
ToJString(env, std::to_string(patch.title_id)));
|
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));
|
Common::Android::ToJDouble(env, max),
|
||||||
return GetJBoolean(env, jwasCancelled);
|
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 =
|
jobjectArray jresult = env->NewObjectArray(result.size(), Common::Android::GetStringClass(),
|
||||||
env->NewObjectArray(result.size(), IDCache::GetStringClass(), ToJString(env, ""));
|
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));
|
Common::Android::ToJDouble(env, max),
|
||||||
return GetJBoolean(env, jwasCancelled);
|
Common::Android::ToJDouble(env, progress));
|
||||||
|
return Common::Android::GetJBoolean(env, jwasCancelled);
|
||||||
};
|
};
|
||||||
auto& session = EmulationSession::GetInstance();
|
auto& session = EmulationSession::GetInstance();
|
||||||
return static_cast<jint>(
|
return static_cast<jint>(ContentManager::VerifyGameContents(
|
||||||
ContentManager::VerifyGameContents(session.System(), GetJString(env, jpath), callback));
|
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) {
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
jclass gameDirClass = Common::Android::GetGameDirClass();
|
||||||
jmethodID gameDirConstructor = IDCache::GetGameDirConstructor();
|
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 =
|
jobject jgameDir = env->NewObject(
|
||||||
env->NewObject(gameDirClass, gameDirConstructor,
|
gameDirClass, gameDirConstructor,
|
||||||
ToJString(env, AndroidSettings::values.game_dirs[i].path),
|
Common::Android::ToJString(env, AndroidSettings::values.game_dirs[i].path),
|
||||||
static_cast<jboolean>(AndroidSettings::values.game_dirs[i].deep_scan));
|
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(),
|
env->NewObject(Common::Android::GetPairClass(), Common::Android::GetPairConstructor(),
|
||||||
ToJDouble(env, control_data.landscape_position.first),
|
Common::Android::ToJDouble(env, control_data.landscape_position.first),
|
||||||
ToJDouble(env, control_data.landscape_position.second));
|
Common::Android::ToJDouble(env, control_data.landscape_position.second));
|
||||||
jobject jportraitPosition =
|
jobject jportraitPosition =
|
||||||
env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(),
|
env->NewObject(Common::Android::GetPairClass(), Common::Android::GetPairConstructor(),
|
||||||
ToJDouble(env, control_data.portrait_position.first),
|
Common::Android::ToJDouble(env, control_data.portrait_position.first),
|
||||||
ToJDouble(env, control_data.portrait_position.second));
|
Common::Android::ToJDouble(env, control_data.portrait_position.second));
|
||||||
jobject jfoldablePosition =
|
jobject jfoldablePosition =
|
||||||
env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(),
|
env->NewObject(Common::Android::GetPairClass(), Common::Android::GetPairConstructor(),
|
||||||
ToJDouble(env, control_data.foldable_position.first),
|
Common::Android::ToJDouble(env, control_data.foldable_position.first),
|
||||||
ToJDouble(env, control_data.foldable_position.second));
|
Common::Android::ToJDouble(env, control_data.foldable_position.second));
|
||||||
|
|
||||||
jobject jcontrolData = env->NewObject(
|
jobject jcontrolData =
|
||||||
IDCache::GetOverlayControlDataClass(), IDCache::GetOverlayControlDataConstructor(),
|
env->NewObject(Common::Android::GetOverlayControlDataClass(),
|
||||||
ToJString(env, control_data.id), control_data.enabled, jlandscapePosition,
|
Common::Android::GetOverlayControlDataConstructor(),
|
||||||
jportraitPosition, jfoldablePosition);
|
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>(
|
jstring jidString = static_cast<jstring>(env->GetObjectField(
|
||||||
env->GetObjectField(joverlayControlData, IDCache::GetOverlayControlDataIdField()));
|
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())),
|
Common::Android::GetJDouble(
|
||||||
GetJDouble(env,
|
env, env->GetObjectField(jlandscapePosition, Common::Android::GetPairFirstField())),
|
||||||
env->GetObjectField(jlandscapePosition, IDCache::GetPairSecondField())));
|
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())),
|
Common::Android::GetJDouble(
|
||||||
GetJDouble(env, env->GetObjectField(jportraitPosition, IDCache::GetPairSecondField())));
|
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())),
|
Common::Android::GetJDouble(
|
||||||
GetJDouble(env, env->GetObjectField(jfoldablePosition, IDCache::GetPairSecondField())));
|
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,
|
Common::Android::GetJString(env, jidString), enabled, landscape_position,
|
||||||
foldable_position});
|
portrait_position, foldable_position});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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(
|
GetEnvForThread()->CallStaticVoidMethod(s_software_keyboard_class, s_swkbd_execute_inline,
|
||||||
s_software_keyboard_class, s_swkbd_execute_inline, ToJKeyboardParams(parameters));
|
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
|
|
@ -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" {
|
|
@ -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
|
|
@ -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
|
|
@ -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) \
|
s_get_parent_directory = env->GetStaticMethodID(native_library, "getParentDirectory",
|
||||||
F(JMethodID, JMethodName, Signature)
|
"(Ljava/lang/String;)Ljava/lang/String;");
|
||||||
#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \
|
s_get_filename = env->GetStaticMethodID(native_library, "getFilename",
|
||||||
F(JMethodID, JMethodName, Signature)
|
"(Ljava/lang/String;)Ljava/lang/String;");
|
||||||
#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) \
|
s_get_size = env->GetStaticMethodID(native_library, "getSize", "(Ljava/lang/String;)J");
|
||||||
F(JMethodID, JMethodName, Signature)
|
s_is_directory = env->GetStaticMethodID(native_library, "isDirectory", "(Ljava/lang/String;)Z");
|
||||||
#define F(JMethodID, JMethodName, Signature) \
|
s_file_exists = env->GetStaticMethodID(native_library, "exists", "(Ljava/lang/String;)Z");
|
||||||
JMethodID = env->GetStaticMethodID(native_library, JMethodName, Signature);
|
s_open_content_uri = env->GetStaticMethodID(native_library, "openContentUri",
|
||||||
ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
|
"(Ljava/lang/String;Ljava/lang/String;)I");
|
||||||
ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
|
|
||||||
ANDROID_STORAGE_FUNCTIONS(FS)
|
|
||||||
#undef F
|
|
||||||
#undef FS
|
|
||||||
#undef FR
|
|
||||||
#undef FH
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnRegisterCallbacks() {
|
void UnRegisterCallbacks() {
|
||||||
#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
|
s_get_parent_directory = nullptr;
|
||||||
#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
|
s_get_filename = nullptr;
|
||||||
#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID)
|
|
||||||
#define F(JMethodID) JMethodID = nullptr;
|
s_get_size = nullptr;
|
||||||
ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
|
s_is_directory = nullptr;
|
||||||
ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
|
s_file_exists = nullptr;
|
||||||
ANDROID_STORAGE_FUNCTIONS(FS)
|
|
||||||
#undef F
|
s_open_content_uri = nullptr;
|
||||||
#undef FS
|
|
||||||
#undef FR
|
|
||||||
#undef FH
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
s32 OpenContentUri(const std::string& filepath, OpenMode openmode) {
|
||||||
if (open_content_uri == nullptr)
|
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();
|
auto env = Common::Android::GetEnvForThread();
|
||||||
jstring j_filepath = env->NewStringUTF(filepath.c_str());
|
jstring j_filepath = Common::Android::ToJString(env, filepath);
|
||||||
jstring j_mode = env->NewStringUTF(mode);
|
jstring j_mode = Common::Android::ToJString(env, mode);
|
||||||
return env->CallStaticIntMethod(native_library, open_content_uri, j_filepath, j_mode);
|
return env->CallStaticIntMethod(native_library, s_open_content_uri, j_filepath, j_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \
|
u64 GetSize(const std::string& filepath) {
|
||||||
F(FunctionName, ReturnValue, JMethodID, Caller)
|
if (s_get_size == nullptr) {
|
||||||
#define F(FunctionName, ReturnValue, JMethodID, Caller) \
|
return 0;
|
||||||
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); \
|
|
||||||
}
|
}
|
||||||
ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
|
auto env = Common::Android::GetEnvForThread();
|
||||||
#undef F
|
return static_cast<u64>(env->CallStaticLongMethod(
|
||||||
#undef FR
|
native_library, s_get_size,
|
||||||
|
Common::Android::ToJString(Common::Android::GetEnvForThread(), filepath)));
|
||||||
|
}
|
||||||
|
|
||||||
#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) \
|
bool IsDirectory(const std::string& filepath) {
|
||||||
F(FunctionName, JMethodID, Caller)
|
if (s_is_directory == nullptr) {
|
||||||
#define F(FunctionName, JMethodID, Caller) \
|
return 0;
|
||||||
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; \
|
|
||||||
}
|
}
|
||||||
ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
|
auto env = Common::Android::GetEnvForThread();
|
||||||
#undef F
|
return env->CallStaticBooleanMethod(
|
||||||
#undef FH
|
native_library, s_is_directory,
|
||||||
|
Common::Android::ToJString(Common::Android::GetEnvForThread(), filepath));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Exists(const std::string& filepath) {
|
||||||
|
if (s_file_exists == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
|
@ -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)
|
static jmethodID s_get_parent_directory;
|
||||||
#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
|
static jmethodID s_get_filename;
|
||||||
#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID)
|
static jmethodID s_get_size;
|
||||||
#define F(JMethodID) static jmethodID JMethodID = nullptr;
|
static jmethodID s_is_directory;
|
||||||
ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
|
static jmethodID s_file_exists;
|
||||||
ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
|
static jmethodID s_open_content_uri;
|
||||||
ANDROID_STORAGE_FUNCTIONS(FS)
|
|
||||||
#undef F
|
|
||||||
#undef FS
|
|
||||||
#undef FR
|
|
||||||
#undef FH
|
|
||||||
|
|
||||||
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) \
|
int OpenContentUri(const std::string& filepath, OpenMode openmode);
|
||||||
F(FunctionName, Parameters, ReturnValue)
|
std::uint64_t GetSize(const std::string& filepath);
|
||||||
#define F(FunctionName, Parameters, ReturnValue) ReturnValue FunctionName Parameters;
|
bool IsDirectory(const std::string& filepath);
|
||||||
ANDROID_STORAGE_FUNCTIONS(FS)
|
bool Exists(const std::string& filepath);
|
||||||
#undef F
|
std::string GetParentDirectory(const std::string& filepath);
|
||||||
#undef FS
|
std::string GetFilename(const std::string& filepath);
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
} // namespace Common::FS::Android
|
} // namespace Common::FS::Android
|
||||||
|
|
Loading…
Reference in a new issue