Browse Source
Merge pull request #11908 from t895/log-spam
Merge pull request #11908 from t895/log-spam
android: Fix URI parsing in native codepull/15/merge
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 662 additions and 516 deletions
-
62src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
-
2src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
-
17src/android/app/src/main/java/org/yuzu/yuzu_emu/model/Game.kt
-
9src/android/app/src/main/java/org/yuzu/yuzu_emu/model/GamesViewModel.kt
-
17src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt
-
4src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt
-
17src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt
-
3src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt
-
20src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameMetadata.kt
-
2src/android/app/src/main/jni/CMakeLists.txt
-
112src/android/app/src/main/jni/game_metadata.cpp
-
289src/android/app/src/main/jni/native.cpp
-
84src/android/app/src/main/jni/native.h
-
33src/common/fs/fs_android.cpp
-
15src/common/fs/fs_android.h
-
10src/common/fs/path_util.cpp
-
12src/common/string_util.cpp
@ -0,0 +1,20 @@ |
|||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
||||
|
// SPDX-License-Identifier: GPL-2.0-or-later |
||||
|
|
||||
|
package org.yuzu.yuzu_emu.utils |
||||
|
|
||||
|
object GameMetadata { |
||||
|
external fun getTitle(path: String): String |
||||
|
|
||||
|
external fun getProgramId(path: String): String |
||||
|
|
||||
|
external fun getDeveloper(path: String): String |
||||
|
|
||||
|
external fun getVersion(path: String): String |
||||
|
|
||||
|
external fun getIcon(path: String): ByteArray |
||||
|
|
||||
|
external fun getIsHomebrew(path: String): Boolean |
||||
|
|
||||
|
external fun resetMetadata() |
||||
|
} |
||||
@ -0,0 +1,112 @@ |
|||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
|
||||
|
#include <core/core.h>
|
||||
|
#include <core/file_sys/patch_manager.h>
|
||||
|
#include <core/loader/nro.h>
|
||||
|
#include <jni.h>
|
||||
|
#include "core/loader/loader.h"
|
||||
|
#include "jni/android_common/android_common.h"
|
||||
|
#include "native.h"
|
||||
|
|
||||
|
struct RomMetadata { |
||||
|
std::string title; |
||||
|
u64 programId; |
||||
|
std::string developer; |
||||
|
std::string version; |
||||
|
std::vector<u8> icon; |
||||
|
bool isHomebrew; |
||||
|
}; |
||||
|
|
||||
|
std::unordered_map<std::string, RomMetadata> m_rom_metadata_cache; |
||||
|
|
||||
|
RomMetadata CacheRomMetadata(const std::string& path) { |
||||
|
const auto file = |
||||
|
Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path); |
||||
|
auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0); |
||||
|
|
||||
|
RomMetadata entry; |
||||
|
loader->ReadTitle(entry.title); |
||||
|
loader->ReadProgramId(entry.programId); |
||||
|
loader->ReadIcon(entry.icon); |
||||
|
|
||||
|
const FileSys::PatchManager pm{ |
||||
|
entry.programId, EmulationSession::GetInstance().System().GetFileSystemController(), |
||||
|
EmulationSession::GetInstance().System().GetContentProvider()}; |
||||
|
const auto control = pm.GetControlMetadata(); |
||||
|
|
||||
|
if (control.first != nullptr) { |
||||
|
entry.developer = control.first->GetDeveloperName(); |
||||
|
entry.version = control.first->GetVersionString(); |
||||
|
} else { |
||||
|
FileSys::NACP nacp; |
||||
|
if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success) { |
||||
|
entry.developer = nacp.GetDeveloperName(); |
||||
|
} else { |
||||
|
entry.developer = ""; |
||||
|
} |
||||
|
|
||||
|
entry.version = "1.0.0"; |
||||
|
} |
||||
|
|
||||
|
if (loader->GetFileType() == Loader::FileType::NRO) { |
||||
|
auto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get()); |
||||
|
entry.isHomebrew = loader_nro->IsHomebrew(); |
||||
|
} else { |
||||
|
entry.isHomebrew = false; |
||||
|
} |
||||
|
|
||||
|
m_rom_metadata_cache[path] = entry; |
||||
|
|
||||
|
return entry; |
||||
|
} |
||||
|
|
||||
|
RomMetadata GetRomMetadata(const std::string& path) { |
||||
|
if (auto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) { |
||||
|
return search->second; |
||||
|
} |
||||
|
|
||||
|
return CacheRomMetadata(path); |
||||
|
} |
||||
|
|
||||
|
extern "C" { |
||||
|
|
||||
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getTitle(JNIEnv* env, jobject obj, |
||||
|
jstring jpath) { |
||||
|
return ToJString(env, GetRomMetadata(GetJString(env, jpath)).title); |
||||
|
} |
||||
|
|
||||
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getProgramId(JNIEnv* env, jobject obj, |
||||
|
jstring jpath) { |
||||
|
return ToJString(env, std::to_string(GetRomMetadata(GetJString(env, jpath)).programId)); |
||||
|
} |
||||
|
|
||||
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getDeveloper(JNIEnv* env, jobject obj, |
||||
|
jstring jpath) { |
||||
|
return ToJString(env, GetRomMetadata(GetJString(env, jpath)).developer); |
||||
|
} |
||||
|
|
||||
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getVersion(JNIEnv* env, jobject obj, |
||||
|
jstring jpath) { |
||||
|
return ToJString(env, GetRomMetadata(GetJString(env, jpath)).version); |
||||
|
} |
||||
|
|
||||
|
jbyteArray Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIcon(JNIEnv* env, jobject obj, |
||||
|
jstring jpath) { |
||||
|
auto icon_data = GetRomMetadata(GetJString(env, jpath)).icon; |
||||
|
jbyteArray icon = env->NewByteArray(static_cast<jsize>(icon_data.size())); |
||||
|
env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon), |
||||
|
reinterpret_cast<jbyte*>(icon_data.data())); |
||||
|
return icon; |
||||
|
} |
||||
|
|
||||
|
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsHomebrew(JNIEnv* env, jobject obj, |
||||
|
jstring jpath) { |
||||
|
return static_cast<jboolean>(GetRomMetadata(GetJString(env, jpath)).isHomebrew); |
||||
|
} |
||||
|
|
||||
|
void Java_org_yuzu_yuzu_1emu_utils_GameMetadata_resetMetadata(JNIEnv* env, jobject obj) { |
||||
|
return m_rom_metadata_cache.clear(); |
||||
|
} |
||||
|
|
||||
|
} // extern "C"
|
||||
@ -0,0 +1,84 @@ |
|||||
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
||||
|
// SPDX-License-Identifier: GPL-2.0-or-later |
||||
|
|
||||
|
#include <android/native_window_jni.h> |
||||
|
#include "common/detached_tasks.h" |
||||
|
#include "core/core.h" |
||||
|
#include "core/file_sys/registered_cache.h" |
||||
|
#include "core/hle/service/acc/profile_manager.h" |
||||
|
#include "core/perf_stats.h" |
||||
|
#include "jni/applets/software_keyboard.h" |
||||
|
#include "jni/emu_window/emu_window.h" |
||||
|
#include "video_core/rasterizer_interface.h" |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
class EmulationSession final { |
||||
|
public: |
||||
|
explicit EmulationSession(); |
||||
|
~EmulationSession() = default; |
||||
|
|
||||
|
static EmulationSession& GetInstance(); |
||||
|
const Core::System& System() const; |
||||
|
Core::System& System(); |
||||
|
|
||||
|
const EmuWindow_Android& Window() const; |
||||
|
EmuWindow_Android& Window(); |
||||
|
ANativeWindow* NativeWindow() const; |
||||
|
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); |
||||
|
|
||||
|
bool IsRunning() const; |
||||
|
bool IsPaused() const; |
||||
|
void PauseEmulation(); |
||||
|
void UnPauseEmulation(); |
||||
|
void HaltEmulation(); |
||||
|
void RunEmulation(); |
||||
|
void ShutdownEmulation(); |
||||
|
|
||||
|
const Core::PerfStatsResults& PerfStats() const; |
||||
|
void ConfigureFilesystemProvider(const std::string& filepath); |
||||
|
Core::SystemResultStatus InitializeEmulation(const std::string& filepath); |
||||
|
|
||||
|
bool IsHandheldOnly(); |
||||
|
void SetDeviceType([[maybe_unused]] int index, int type); |
||||
|
void OnGamepadConnectEvent([[maybe_unused]] int index); |
||||
|
void OnGamepadDisconnectEvent([[maybe_unused]] int index); |
||||
|
SoftwareKeyboard::AndroidKeyboard* SoftwareKeyboard(); |
||||
|
|
||||
|
private: |
||||
|
static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max); |
||||
|
static void OnEmulationStarted(); |
||||
|
static void OnEmulationStopped(Core::SystemResultStatus result); |
||||
|
|
||||
|
private: |
||||
|
// Window management |
||||
|
std::unique_ptr<EmuWindow_Android> m_window; |
||||
|
ANativeWindow* m_native_window{}; |
||||
|
|
||||
|
// Core emulation |
||||
|
Core::System m_system; |
||||
|
InputCommon::InputSubsystem m_input_subsystem; |
||||
|
Common::DetachedTasks m_detached_tasks; |
||||
|
Core::PerfStatsResults m_perf_stats{}; |
||||
|
std::shared_ptr<FileSys::VfsFilesystem> m_vfs; |
||||
|
Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized}; |
||||
|
std::atomic<bool> m_is_running = false; |
||||
|
std::atomic<bool> m_is_paused = false; |
||||
|
SoftwareKeyboard::AndroidKeyboard* m_software_keyboard{}; |
||||
|
std::unique_ptr<Service::Account::ProfileManager> m_profile_manager; |
||||
|
std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider; |
||||
|
|
||||
|
// GPU driver parameters |
||||
|
std::shared_ptr<Common::DynamicLibrary> m_vulkan_library; |
||||
|
|
||||
|
// Synchronization |
||||
|
std::condition_variable_any m_cv; |
||||
|
mutable std::mutex m_perf_stats_mutex; |
||||
|
mutable std::mutex m_mutex; |
||||
|
}; |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue