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/id_cache.cpp40
-rw-r--r--src/android/app/src/main/jni/id_cache.h6
-rw-r--r--src/android/app/src/main/jni/native.cpp108
-rw-r--r--src/android/app/src/main/jni/native.h2
-rw-r--r--src/android/app/src/main/jni/native_config.cpp26
5 files changed, 172 insertions, 10 deletions
diff --git a/src/android/app/src/main/jni/id_cache.cpp b/src/android/app/src/main/jni/id_cache.cpp
index a56ed5662..df8935178 100644
--- a/src/android/app/src/main/jni/id_cache.cpp
+++ b/src/android/app/src/main/jni/id_cache.cpp
@@ -20,6 +20,12 @@ static jmethodID s_disk_cache_load_progress;
static jmethodID s_on_emulation_started;
static jmethodID s_on_emulation_stopped;
+static jclass s_string_class;
+static jclass s_pair_class;
+static jmethodID s_pair_constructor;
+static jfieldID s_pair_first_field;
+static jfieldID s_pair_second_field;
+
static constexpr jint JNI_VERSION = JNI_VERSION_1_6;
namespace IDCache {
@@ -79,6 +85,26 @@ jmethodID GetOnEmulationStopped() {
return s_on_emulation_stopped;
}
+jclass GetStringClass() {
+ return s_string_class;
+}
+
+jclass GetPairClass() {
+ return s_pair_class;
+}
+
+jmethodID GetPairConstructor() {
+ return s_pair_constructor;
+}
+
+jfieldID GetPairFirstField() {
+ return s_pair_first_field;
+}
+
+jfieldID GetPairSecondField() {
+ return s_pair_second_field;
+}
+
} // namespace IDCache
#ifdef __cplusplus
@@ -115,6 +141,18 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
s_on_emulation_stopped =
env->GetStaticMethodID(s_native_library_class, "onEmulationStopped", "(I)V");
+ const jclass string_class = env->FindClass("java/lang/String");
+ s_string_class = reinterpret_cast<jclass>(env->NewGlobalRef(string_class));
+ env->DeleteLocalRef(string_class);
+
+ const jclass pair_class = env->FindClass("kotlin/Pair");
+ s_pair_class = reinterpret_cast<jclass>(env->NewGlobalRef(pair_class));
+ s_pair_constructor =
+ env->GetMethodID(pair_class, "<init>", "(Ljava/lang/Object;Ljava/lang/Object;)V");
+ s_pair_first_field = env->GetFieldID(pair_class, "first", "Ljava/lang/Object;");
+ s_pair_second_field = env->GetFieldID(pair_class, "second", "Ljava/lang/Object;");
+ env->DeleteLocalRef(pair_class);
+
// Initialize Android Storage
Common::FS::Android::RegisterCallbacks(env, s_native_library_class);
@@ -136,6 +174,8 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) {
env->DeleteGlobalRef(s_disk_cache_progress_class);
env->DeleteGlobalRef(s_load_callback_stage_class);
env->DeleteGlobalRef(s_game_dir_class);
+ env->DeleteGlobalRef(s_string_class);
+ env->DeleteGlobalRef(s_pair_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 855649efa..36233423e 100644
--- a/src/android/app/src/main/jni/id_cache.h
+++ b/src/android/app/src/main/jni/id_cache.h
@@ -20,4 +20,10 @@ jmethodID GetDiskCacheLoadProgress();
jmethodID GetOnEmulationStarted();
jmethodID GetOnEmulationStopped();
+jclass GetStringClass();
+jclass GetPairClass();
+jmethodID GetPairConstructor();
+jfieldID GetPairFirstField();
+jfieldID GetPairSecondField();
+
} // namespace IDCache
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index e5d3158c8..ce570b811 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -14,6 +14,7 @@
#include <android/api-level.h>
#include <android/native_window_jni.h>
#include <common/fs/fs.h>
+#include <core/file_sys/patch_manager.h>
#include <core/file_sys/savedata_factory.h>
#include <core/loader/nro.h>
#include <jni.h>
@@ -79,6 +80,10 @@ Core::System& EmulationSession::System() {
return m_system;
}
+FileSys::ManualContentProvider* EmulationSession::ContentProvider() {
+ return m_manual_provider.get();
+}
+
const EmuWindow_Android& EmulationSession::Window() const {
return *m_window;
}
@@ -455,6 +460,15 @@ void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) {
static_cast<jint>(result));
}
+u64 EmulationSession::GetProgramId(JNIEnv* env, jstring jprogramId) {
+ auto program_id_string = GetJString(env, jprogramId);
+ try {
+ return std::stoull(program_id_string);
+ } catch (...) {
+ return 0;
+ }
+}
+
static Core::SystemResultStatus RunEmulation(const std::string& filepath) {
MicroProfileOnThreadCreate("EmuThread");
SCOPE_EXIT({ MicroProfileShutdown(); });
@@ -504,6 +518,27 @@ int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jobject
GetJString(env, j_file_extension));
}
+jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* env, jobject jobj,
+ jstring jprogramId,
+ jstring jupdatePath) {
+ u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
+ std::string updatePath = GetJString(env, jupdatePath);
+ std::shared_ptr<FileSys::NSP> nsp = std::make_shared<FileSys::NSP>(
+ EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(updatePath,
+ FileSys::Mode::Read));
+ for (const auto& item : nsp->GetNCAs()) {
+ for (const auto& nca_details : item.second) {
+ if (nca_details.second->GetName().ends_with(".cnmt.nca")) {
+ auto update_id = nca_details.second->GetTitleId() & ~0xFFFULL;
+ if (update_id == program_id) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeGpuDriver(JNIEnv* env, jclass clazz,
jstring hook_lib_dir,
jstring custom_driver_dir,
@@ -665,13 +700,6 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeSystem(JNIEnv* env, jclass
EmulationSession::GetInstance().InitializeSystem(reload);
}
-jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore(JNIEnv* env, jclass clazz) {
- return {};
-}
-
-void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2Ljava_lang_String_2Z(
- JNIEnv* env, jclass clazz, jstring j_file, jstring j_savestate, jboolean j_delete_savestate) {}
-
jdoubleArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPerfStats(JNIEnv* env, jclass clazz) {
jdoubleArray j_stats = env->NewDoubleArray(4);
@@ -696,9 +724,13 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuBackend(JNIEnv* env, jclass
return ToJString(env, "JIT");
}
-void Java_org_yuzu_yuzu_1emu_utils_DirectoryInitialization_setSysDirectory(JNIEnv* env,
- jclass clazz,
- jstring j_path) {}
+void Java_org_yuzu_yuzu_1emu_NativeLibrary_applySettings(JNIEnv* env, jobject jobj) {
+ EmulationSession::GetInstance().System().ApplySettings();
+}
+
+void Java_org_yuzu_yuzu_1emu_NativeLibrary_logSettings(JNIEnv* env, jobject jobj) {
+ Settings::LogSettings();
+}
void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2(JNIEnv* env, jclass clazz,
jstring j_path) {
@@ -792,4 +824,60 @@ 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) {
+ const auto path = GetJString(env, jpath);
+ const auto vFile =
+ Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path);
+ if (vFile == nullptr) {
+ return nullptr;
+ }
+
+ auto& system = EmulationSession::GetInstance().System();
+ auto program_id = EmulationSession::GetProgramId(env, jprogramId);
+ const FileSys::PatchManager pm{program_id, system.GetFileSystemController(),
+ system.GetContentProvider()};
+ const auto loader = Loader::GetLoader(system, vFile);
+
+ 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);
+ 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);
+ ++i;
+ }
+ return jaddonsArray;
+}
+
+jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject jobj,
+ jstring jprogramId) {
+ auto program_id = EmulationSession::GetProgramId(env, jprogramId);
+
+ auto& system = EmulationSession::GetInstance().System();
+
+ Service::Account::ProfileManager manager;
+ // TODO: Pass in a selected user once we get the relevant UI working
+ const auto user_id = manager.GetUser(static_cast<std::size_t>(0));
+ ASSERT(user_id);
+
+ const auto nandDir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir);
+ auto vfsNandDir = system.GetFilesystem()->OpenDirectory(Common::FS::PathToUTF8String(nandDir),
+ FileSys::Mode::Read);
+
+ const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
+ system, vfsNandDir, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
+ program_id, user_id->AsU128(), 0);
+ return ToJString(env, user_save_data_path);
+}
+
} // extern "C"
diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h
index f1457bd1f..96c22d52b 100644
--- a/src/android/app/src/main/jni/native.h
+++ b/src/android/app/src/main/jni/native.h
@@ -54,6 +54,8 @@ public:
static void OnEmulationStarted();
+ static u64 GetProgramId(JNIEnv* env, jstring jprogramId);
+
private:
static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max);
static void OnEmulationStopped(Core::SystemResultStatus result);
diff --git a/src/android/app/src/main/jni/native_config.cpp b/src/android/app/src/main/jni/native_config.cpp
index 9439d11e1..7f2485720 100644
--- a/src/android/app/src/main/jni/native_config.cpp
+++ b/src/android/app/src/main/jni/native_config.cpp
@@ -283,4 +283,30 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_addGameDir(JNIEnv* env, jobject
AndroidSettings::GameDir{uriString, static_cast<bool>(jdeepScanBoolean)});
}
+jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getDisabledAddons(JNIEnv* env, jobject obj,
+ jstring jprogramId) {
+ auto program_id = EmulationSession::GetProgramId(env, jprogramId);
+ auto& disabledAddons = Settings::values.disabled_addons[program_id];
+ jobjectArray jdisabledAddonsArray =
+ env->NewObjectArray(disabledAddons.size(), IDCache::GetStringClass(), ToJString(env, ""));
+ for (size_t i = 0; i < disabledAddons.size(); ++i) {
+ env->SetObjectArrayElement(jdisabledAddonsArray, i, ToJString(env, disabledAddons[i]));
+ }
+ return jdisabledAddonsArray;
+}
+
+void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setDisabledAddons(JNIEnv* env, jobject obj,
+ jstring jprogramId,
+ jobjectArray jdisabledAddons) {
+ auto program_id = EmulationSession::GetProgramId(env, jprogramId);
+ Settings::values.disabled_addons[program_id].clear();
+ std::vector<std::string> disabled_addons;
+ const int size = env->GetArrayLength(jdisabledAddons);
+ for (int i = 0; i < size; ++i) {
+ auto jaddon = static_cast<jstring>(env->GetObjectArrayElement(jdisabledAddons, i));
+ disabled_addons.push_back(GetJString(env, jaddon));
+ }
+ Settings::values.disabled_addons[program_id] = disabled_addons;
+}
+
} // extern "C"