summaryrefslogtreecommitdiffstats
path: root/src/android/app/src/main/jni
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/app/src/main/jni')
-rw-r--r--src/android/app/src/main/jni/android_common/android_common.cpp16
-rw-r--r--src/android/app/src/main/jni/android_common/android_common.h7
-rw-r--r--src/android/app/src/main/jni/id_cache.cpp101
-rw-r--r--src/android/app/src/main/jni/id_cache.h17
-rw-r--r--src/android/app/src/main/jni/native.cpp128
-rw-r--r--src/android/app/src/main/jni/native.h2
6 files changed, 191 insertions, 80 deletions
diff --git a/src/android/app/src/main/jni/android_common/android_common.cpp b/src/android/app/src/main/jni/android_common/android_common.cpp
index 1e884ffdd..7018a52af 100644
--- a/src/android/app/src/main/jni/android_common/android_common.cpp
+++ b/src/android/app/src/main/jni/android_common/android_common.cpp
@@ -42,3 +42,19 @@ double GetJDouble(JNIEnv* env, jobject jdouble) {
jobject ToJDouble(JNIEnv* env, double value) {
return env->NewObject(IDCache::GetDoubleClass(), IDCache::GetDoubleConstructor(), value);
}
+
+s32 GetJInteger(JNIEnv* env, jobject jinteger) {
+ return env->GetIntField(jinteger, IDCache::GetIntegerValueField());
+}
+
+jobject ToJInteger(JNIEnv* env, s32 value) {
+ return env->NewObject(IDCache::GetIntegerClass(), IDCache::GetIntegerConstructor(), value);
+}
+
+bool GetJBoolean(JNIEnv* env, jobject jboolean) {
+ return env->GetBooleanField(jboolean, IDCache::GetBooleanValueField());
+}
+
+jobject ToJBoolean(JNIEnv* env, bool value) {
+ return env->NewObject(IDCache::GetBooleanClass(), IDCache::GetBooleanConstructor(), value);
+}
diff --git a/src/android/app/src/main/jni/android_common/android_common.h b/src/android/app/src/main/jni/android_common/android_common.h
index 8eb803e1b..29a338c0a 100644
--- a/src/android/app/src/main/jni/android_common/android_common.h
+++ b/src/android/app/src/main/jni/android_common/android_common.h
@@ -6,6 +6,7 @@
#include <string>
#include <jni.h>
+#include "common/common_types.h"
std::string GetJString(JNIEnv* env, jstring jstr);
jstring ToJString(JNIEnv* env, std::string_view str);
@@ -13,3 +14,9 @@ jstring ToJString(JNIEnv* env, std::u16string_view str);
double GetJDouble(JNIEnv* env, jobject jdouble);
jobject ToJDouble(JNIEnv* env, double value);
+
+s32 GetJInteger(JNIEnv* env, jobject jinteger);
+jobject ToJInteger(JNIEnv* env, s32 value);
+
+bool GetJBoolean(JNIEnv* env, jobject jboolean);
+jobject ToJBoolean(JNIEnv* env, bool value);
diff --git a/src/android/app/src/main/jni/id_cache.cpp b/src/android/app/src/main/jni/id_cache.cpp
index c79ad7d76..96f2ad3d4 100644
--- a/src/android/app/src/main/jni/id_cache.cpp
+++ b/src/android/app/src/main/jni/id_cache.cpp
@@ -43,10 +43,27 @@ static jfieldID s_overlay_control_data_landscape_position_field;
static jfieldID s_overlay_control_data_portrait_position_field;
static jfieldID s_overlay_control_data_foldable_position_field;
+static jclass s_patch_class;
+static jmethodID s_patch_constructor;
+static jfieldID s_patch_enabled_field;
+static jfieldID s_patch_name_field;
+static jfieldID s_patch_version_field;
+static jfieldID s_patch_type_field;
+static jfieldID s_patch_program_id_field;
+static jfieldID s_patch_title_id_field;
+
static jclass s_double_class;
static jmethodID s_double_constructor;
static jfieldID s_double_value_field;
+static jclass s_integer_class;
+static jmethodID s_integer_constructor;
+static jfieldID s_integer_value_field;
+
+static jclass s_boolean_class;
+static jmethodID s_boolean_constructor;
+static jfieldID s_boolean_value_field;
+
static constexpr jint JNI_VERSION = JNI_VERSION_1_6;
namespace IDCache {
@@ -186,6 +203,38 @@ jfieldID GetOverlayControlDataFoldablePositionField() {
return s_overlay_control_data_foldable_position_field;
}
+jclass GetPatchClass() {
+ return s_patch_class;
+}
+
+jmethodID GetPatchConstructor() {
+ return s_patch_constructor;
+}
+
+jfieldID GetPatchEnabledField() {
+ return s_patch_enabled_field;
+}
+
+jfieldID GetPatchNameField() {
+ return s_patch_name_field;
+}
+
+jfieldID GetPatchVersionField() {
+ return s_patch_version_field;
+}
+
+jfieldID GetPatchTypeField() {
+ return s_patch_type_field;
+}
+
+jfieldID GetPatchProgramIdField() {
+ return s_patch_program_id_field;
+}
+
+jfieldID GetPatchTitleIdField() {
+ return s_patch_title_id_field;
+}
+
jclass GetDoubleClass() {
return s_double_class;
}
@@ -198,6 +247,30 @@ jfieldID GetDoubleValueField() {
return s_double_value_field;
}
+jclass GetIntegerClass() {
+ return s_integer_class;
+}
+
+jmethodID GetIntegerConstructor() {
+ return s_integer_constructor;
+}
+
+jfieldID GetIntegerValueField() {
+ return s_integer_value_field;
+}
+
+jclass GetBooleanClass() {
+ return s_boolean_class;
+}
+
+jmethodID GetBooleanConstructor() {
+ return s_boolean_constructor;
+}
+
+jfieldID GetBooleanValueField() {
+ return s_boolean_value_field;
+}
+
} // namespace IDCache
#ifdef __cplusplus
@@ -278,12 +351,37 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
env->GetFieldID(overlay_control_data_class, "foldablePosition", "Lkotlin/Pair;");
env->DeleteLocalRef(overlay_control_data_class);
+ const jclass patch_class = env->FindClass("org/yuzu/yuzu_emu/model/Patch");
+ s_patch_class = reinterpret_cast<jclass>(env->NewGlobalRef(patch_class));
+ s_patch_constructor = env->GetMethodID(
+ patch_class, "<init>",
+ "(ZLjava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V");
+ s_patch_enabled_field = env->GetFieldID(patch_class, "enabled", "Z");
+ s_patch_name_field = env->GetFieldID(patch_class, "name", "Ljava/lang/String;");
+ s_patch_version_field = env->GetFieldID(patch_class, "version", "Ljava/lang/String;");
+ s_patch_type_field = env->GetFieldID(patch_class, "type", "I");
+ s_patch_program_id_field = env->GetFieldID(patch_class, "programId", "Ljava/lang/String;");
+ s_patch_title_id_field = env->GetFieldID(patch_class, "titleId", "Ljava/lang/String;");
+ env->DeleteLocalRef(patch_class);
+
const jclass double_class = env->FindClass("java/lang/Double");
s_double_class = reinterpret_cast<jclass>(env->NewGlobalRef(double_class));
s_double_constructor = env->GetMethodID(double_class, "<init>", "(D)V");
s_double_value_field = env->GetFieldID(double_class, "value", "D");
env->DeleteLocalRef(double_class);
+ const jclass int_class = env->FindClass("java/lang/Integer");
+ s_integer_class = reinterpret_cast<jclass>(env->NewGlobalRef(int_class));
+ s_integer_constructor = env->GetMethodID(int_class, "<init>", "(I)V");
+ s_integer_value_field = env->GetFieldID(int_class, "value", "I");
+ env->DeleteLocalRef(int_class);
+
+ const jclass boolean_class = env->FindClass("java/lang/Boolean");
+ s_boolean_class = reinterpret_cast<jclass>(env->NewGlobalRef(boolean_class));
+ s_boolean_constructor = env->GetMethodID(boolean_class, "<init>", "(Z)V");
+ s_boolean_value_field = env->GetFieldID(boolean_class, "value", "Z");
+ env->DeleteLocalRef(boolean_class);
+
// Initialize Android Storage
Common::FS::Android::RegisterCallbacks(env, s_native_library_class);
@@ -309,7 +407,10 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) {
env->DeleteGlobalRef(s_string_class);
env->DeleteGlobalRef(s_pair_class);
env->DeleteGlobalRef(s_overlay_control_data_class);
+ env->DeleteGlobalRef(s_patch_class);
env->DeleteGlobalRef(s_double_class);
+ env->DeleteGlobalRef(s_integer_class);
+ env->DeleteGlobalRef(s_boolean_class);
// UnInitialize applets
SoftwareKeyboard::CleanupJNI(env);
diff --git a/src/android/app/src/main/jni/id_cache.h b/src/android/app/src/main/jni/id_cache.h
index 784d1412f..a002e705d 100644
--- a/src/android/app/src/main/jni/id_cache.h
+++ b/src/android/app/src/main/jni/id_cache.h
@@ -43,8 +43,25 @@ jfieldID GetOverlayControlDataLandscapePositionField();
jfieldID GetOverlayControlDataPortraitPositionField();
jfieldID GetOverlayControlDataFoldablePositionField();
+jclass GetPatchClass();
+jmethodID GetPatchConstructor();
+jfieldID GetPatchEnabledField();
+jfieldID GetPatchNameField();
+jfieldID GetPatchVersionField();
+jfieldID GetPatchTypeField();
+jfieldID GetPatchProgramIdField();
+jfieldID GetPatchTitleIdField();
+
jclass GetDoubleClass();
jmethodID GetDoubleConstructor();
jfieldID GetDoubleValueField();
+jclass GetIntegerClass();
+jmethodID GetIntegerConstructor();
+jfieldID GetIntegerValueField();
+
+jclass GetBooleanClass();
+jmethodID GetBooleanConstructor();
+jfieldID GetBooleanValueField();
+
} // namespace IDCache
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index ed3b1353a..be0a723b1 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -17,6 +17,7 @@
#include <core/file_sys/patch_manager.h>
#include <core/file_sys/savedata_factory.h>
#include <core/loader/nro.h>
+#include <frontend_common/content_manager.h>
#include <jni.h>
#include "common/detached_tasks.h"
@@ -100,67 +101,6 @@ void EmulationSession::SetNativeWindow(ANativeWindow* native_window) {
m_native_window = native_window;
}
-int EmulationSession::InstallFileToNand(std::string filename, std::string file_extension) {
- jconst copy_func = [](const FileSys::VirtualFile& src, const FileSys::VirtualFile& dest,
- std::size_t block_size) {
- if (src == nullptr || dest == nullptr) {
- return false;
- }
- if (!dest->Resize(src->GetSize())) {
- return false;
- }
-
- using namespace Common::Literals;
- [[maybe_unused]] std::vector<u8> buffer(1_MiB);
-
- for (std::size_t i = 0; i < src->GetSize(); i += buffer.size()) {
- jconst read = src->Read(buffer.data(), buffer.size(), i);
- dest->Write(buffer.data(), read, i);
- }
- return true;
- };
-
- enum InstallResult {
- Success = 0,
- SuccessFileOverwritten = 1,
- InstallError = 2,
- ErrorBaseGame = 3,
- ErrorFilenameExtension = 4,
- };
-
- [[maybe_unused]] std::shared_ptr<FileSys::NSP> nsp;
- if (file_extension == "nsp") {
- nsp = std::make_shared<FileSys::NSP>(m_vfs->OpenFile(filename, FileSys::Mode::Read));
- if (nsp->IsExtractedType()) {
- return InstallError;
- }
- } else {
- return ErrorFilenameExtension;
- }
-
- if (!nsp) {
- return InstallError;
- }
-
- if (nsp->GetStatus() != Loader::ResultStatus::Success) {
- return InstallError;
- }
-
- jconst res = m_system.GetFileSystemController().GetUserNANDContents()->InstallEntry(*nsp, true,
- copy_func);
-
- switch (res) {
- case FileSys::InstallResult::Success:
- return Success;
- case FileSys::InstallResult::OverwriteExisting:
- return SuccessFileOverwritten;
- case FileSys::InstallResult::ErrorBaseInstall:
- return ErrorBaseGame;
- default:
- return InstallError;
- }
-}
-
void EmulationSession::InitializeGpuDriver(const std::string& hook_lib_dir,
const std::string& custom_driver_dir,
const std::string& custom_driver_name,
@@ -512,10 +452,20 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_setAppDirectory(JNIEnv* env, jobject
}
int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jobject instance,
- jstring j_file,
- jstring j_file_extension) {
- return EmulationSession::GetInstance().InstallFileToNand(GetJString(env, j_file),
- GetJString(env, j_file_extension));
+ jstring j_file, jobject jcallback) {
+ auto jlambdaClass = env->GetObjectClass(jcallback);
+ auto jlambdaInvokeMethod = env->GetMethodID(
+ 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);
+ };
+
+ return static_cast<int>(
+ ContentManager::InstallNSP(&EmulationSession::GetInstance().System(),
+ EmulationSession::GetInstance().System().GetFilesystem().get(),
+ GetJString(env, j_file), callback));
}
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* env, jobject jobj,
@@ -824,9 +774,9 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isFirmwareAvailable(JNIEnv* env,
return true;
}
-jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getAddonsForFile(JNIEnv* env, jobject jobj,
- jstring jpath,
- jstring jprogramId) {
+jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env, jobject jobj,
+ jstring jpath,
+ jstring jprogramId) {
const auto path = GetJString(env, jpath);
const auto vFile =
Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path);
@@ -843,20 +793,40 @@ jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getAddonsForFile(JNIEnv* env,
FileSys::VirtualFile update_raw;
loader->ReadUpdateRaw(update_raw);
- auto addons = pm.GetPatchVersionNames(update_raw);
- auto jemptyString = ToJString(env, "");
- auto jemptyStringPair = env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(),
- jemptyString, jemptyString);
- jobjectArray jaddonsArray =
- env->NewObjectArray(addons.size(), IDCache::GetPairClass(), jemptyStringPair);
+ auto patches = pm.GetPatches(update_raw);
+ jobjectArray jpatchArray =
+ env->NewObjectArray(patches.size(), IDCache::GetPatchClass(), nullptr);
int i = 0;
- for (const auto& addon : addons) {
- jobject jaddon = env->NewObject(IDCache::GetPairClass(), IDCache::GetPairConstructor(),
- ToJString(env, addon.first), ToJString(env, addon.second));
- env->SetObjectArrayElement(jaddonsArray, i, jaddon);
+ 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)));
+ env->SetObjectArrayElement(jpatchArray, i, jpatch);
++i;
}
- return jaddonsArray;
+ return jpatchArray;
+}
+
+void Java_org_yuzu_yuzu_1emu_NativeLibrary_removeUpdate(JNIEnv* env, jobject jobj,
+ jstring jprogramId) {
+ auto program_id = EmulationSession::GetProgramId(env, jprogramId);
+ ContentManager::RemoveUpdate(EmulationSession::GetInstance().System().GetFileSystemController(),
+ program_id);
+}
+
+void Java_org_yuzu_yuzu_1emu_NativeLibrary_removeDLC(JNIEnv* env, jobject jobj,
+ jstring jprogramId) {
+ auto program_id = EmulationSession::GetProgramId(env, jprogramId);
+ ContentManager::RemoveAllDLC(&EmulationSession::GetInstance().System(), program_id);
+}
+
+void Java_org_yuzu_yuzu_1emu_NativeLibrary_removeMod(JNIEnv* env, jobject jobj, jstring jprogramId,
+ jstring jname) {
+ auto program_id = EmulationSession::GetProgramId(env, jprogramId);
+ ContentManager::RemoveMod(EmulationSession::GetInstance().System().GetFileSystemController(),
+ program_id, GetJString(env, jname));
}
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(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 4a8049578..dadb138ad 100644
--- a/src/android/app/src/main/jni/native.h
+++ b/src/android/app/src/main/jni/native.h
@@ -7,6 +7,7 @@
#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"
@@ -29,7 +30,6 @@ public:
void SetNativeWindow(ANativeWindow* native_window);
void SurfaceChanged();
- int InstallFileToNand(std::string filename, std::string file_extension);
void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir,
const std::string& custom_driver_name,
const std::string& file_redirect_dir);