summaryrefslogtreecommitdiffstats
path: root/src/android/app/src/main/jni/native.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/app/src/main/jni/native.cpp')
-rw-r--r--src/android/app/src/main/jni/native.cpp86
1 files changed, 82 insertions, 4 deletions
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 7ebed5e6a..4091c23d1 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -28,7 +28,10 @@
#include "core/core.h"
#include "core/cpu_manager.h"
#include "core/crypto/key_manager.h"
+#include "core/file_sys/card_image.h"
#include "core/file_sys/registered_cache.h"
+#include "core/file_sys/submission_package.h"
+#include "core/file_sys/vfs.h"
#include "core/file_sys/vfs_real.h"
#include "core/frontend/applets/cabinet.h"
#include "core/frontend/applets/controller.h"
@@ -94,6 +97,74 @@ public:
m_native_window = native_window;
}
+ int InstallFileToNand(std::string filename) {
+ const auto 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;
+ std::vector<u8> buffer(1_MiB);
+
+ for (std::size_t i = 0; i < src->GetSize(); i += buffer.size()) {
+ const auto 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,
+ };
+
+ m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
+ m_system.GetFileSystemController().CreateFactories(*m_vfs);
+
+ std::shared_ptr<FileSys::NSP> nsp;
+ if (filename.ends_with("nsp")) {
+ nsp = std::make_shared<FileSys::NSP>(m_vfs->OpenFile(filename, FileSys::Mode::Read));
+ if (nsp->IsExtractedType()) {
+ return InstallError;
+ }
+ } else if (filename.ends_with("xci")) {
+ const auto xci =
+ std::make_shared<FileSys::XCI>(m_vfs->OpenFile(filename, FileSys::Mode::Read));
+ nsp = xci->GetSecurePartitionNSP();
+ } else {
+ return ErrorFilenameExtension;
+ }
+
+ if (!nsp) {
+ return InstallError;
+ }
+
+ if (nsp->GetStatus() != Loader::ResultStatus::Success) {
+ return InstallError;
+ }
+
+ const auto 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 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) {
@@ -154,14 +225,14 @@ public:
m_window = std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window,
m_vulkan_library);
+ m_system.SetFilesystem(m_vfs);
+
// Initialize system.
auto android_keyboard = std::make_unique<SoftwareKeyboard::AndroidKeyboard>();
m_software_keyboard = android_keyboard.get();
m_system.SetShuttingDown(false);
m_system.ApplySettings();
m_system.HIDCore().ReloadInputDevices();
- m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
- m_system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
m_system.SetAppletFrontendSet({
nullptr, // Amiibo Settings
nullptr, // Controller Selector
@@ -173,7 +244,8 @@ public:
std::move(android_keyboard), // Software Keyboard
nullptr, // Web Browser
});
- m_system.GetFileSystemController().CreateFactories(*m_system.GetFilesystem());
+ m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
+ m_system.GetFileSystemController().CreateFactories(*m_vfs);
// Initialize account manager
m_profile_manager = std::make_unique<Service::Account::ProfileManager>();
@@ -398,7 +470,7 @@ private:
InputCommon::InputSubsystem m_input_subsystem;
Common::DetachedTasks m_detached_tasks;
Core::PerfStatsResults m_perf_stats{};
- std::shared_ptr<FileSys::RealVfsFilesystem> m_vfs;
+ std::shared_ptr<FileSys::VfsFilesystem> m_vfs;
Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
bool m_is_running{};
SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{};
@@ -466,6 +538,12 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_setAppDirectory(JNIEnv* env,
Common::FS::SetAppDirectory(GetJString(env, j_directory));
}
+int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env,
+ [[maybe_unused]] jclass clazz,
+ jstring j_file) {
+ return EmulationSession::GetInstance().InstallFileToNand(GetJString(env, j_file));
+}
+
void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeGpuDriver(
JNIEnv* env, [[maybe_unused]] jclass clazz, jstring hook_lib_dir, jstring custom_driver_dir,
jstring custom_driver_name, jstring file_redirect_dir) {