Procházet zdrojové kódy

android: Add game dir entries to FilesystemProvider

Allows us to correctly parse update metadata
t895 před 2 roky
rodič
revize
ac222ceba2

+ 12 - 0
src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt

@@ -547,6 +547,18 @@ object NativeLibrary {
      */
     external fun getSavePath(programId: String): String
 
+    /**
+     * Adds a file to the manual filesystem provider in our EmulationSession instance
+     * @param path Path to the file we're adding. Can be a string representation of a [Uri] or
+     * a normal path
+     */
+    external fun addFileToFilesystemProvider(path: String)
+
+    /**
+     * Clears all files added to the manual filesystem provider in our EmulationSession instance
+     */
+    external fun clearFilesystemProvider()
+
     /**
      * Button type for use in onTouchEvent
      */

+ 19 - 3
src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameHelper.kt

@@ -36,6 +36,12 @@ object GameHelper {
         // Ensure keys are loaded so that ROM metadata can be decrypted.
         NativeLibrary.reloadKeys()
 
+        // Reset metadata so we don't use stale information
+        GameMetadata.resetMetadata()
+
+        // Remove previous filesystem provider information so we can get up to date version info
+        NativeLibrary.clearFilesystemProvider()
+
         val badDirs = mutableListOf<Int>()
         gameDirs.forEachIndexed { index: Int, gameDir: GameDir ->
             val gameDirUri = Uri.parse(gameDir.uriString)
@@ -92,14 +98,24 @@ object GameHelper {
                 )
             } else {
                 if (Game.extensions.contains(FileUtil.getExtension(it.uri))) {
-                    games.add(getGame(it.uri, true))
+                    val game = getGame(it.uri, true)
+                    if (game != null) {
+                        games.add(game)
+                    }
                 }
             }
         }
     }
 
-    fun getGame(uri: Uri, addedToLibrary: Boolean): Game {
+    fun getGame(uri: Uri, addedToLibrary: Boolean): Game? {
         val filePath = uri.toString()
+        if (!GameMetadata.getIsValid(filePath)) {
+            return null
+        }
+
+        // Needed to update installed content information
+        NativeLibrary.addFileToFilesystemProvider(filePath)
+
         var name = GameMetadata.getTitle(filePath)
 
         // If the game's title field is empty, use the filename.
@@ -118,7 +134,7 @@ object GameHelper {
             filePath,
             programId,
             GameMetadata.getDeveloper(filePath),
-            GameMetadata.getVersion(filePath),
+            GameMetadata.getVersion(filePath, false),
             GameMetadata.getIsHomebrew(filePath)
         )
 

+ 3 - 1
src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameMetadata.kt

@@ -4,13 +4,15 @@
 package org.yuzu.yuzu_emu.utils
 
 object GameMetadata {
+    external fun getIsValid(path: String): Boolean
+
     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 getVersion(path: String, reload: Boolean): String
 
     external fun getIcon(path: String): ByteArray
 

+ 35 - 4
src/android/app/src/main/jni/game_metadata.cpp

@@ -2,6 +2,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include <core/core.h>
+#include <core/file_sys/mode.h>
 #include <core/file_sys/patch_manager.h>
 #include <core/loader/nro.h>
 #include <jni.h>
@@ -61,7 +62,11 @@ RomMetadata CacheRomMetadata(const std::string& path) {
     return entry;
 }
 
-RomMetadata GetRomMetadata(const std::string& path) {
+RomMetadata GetRomMetadata(const std::string& path, bool reload = false) {
+    if (reload) {
+        return CacheRomMetadata(path);
+    }
+
     if (auto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) {
         return search->second;
     }
@@ -71,6 +76,32 @@ RomMetadata GetRomMetadata(const std::string& path) {
 
 extern "C" {
 
+jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobject obj,
+                                                               jstring jpath) {
+    const auto file = EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
+        GetJString(env, jpath), FileSys::Mode::Read);
+    if (!file) {
+        return false;
+    }
+
+    auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file);
+    if (!loader) {
+        return false;
+    }
+
+    const auto file_type = loader->GetFileType();
+    if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
+        return false;
+    }
+
+    u64 program_id = 0;
+    Loader::ResultStatus res = loader->ReadProgramId(program_id);
+    if (res != Loader::ResultStatus::Success) {
+        return false;
+    }
+    return true;
+}
+
 jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getTitle(JNIEnv* env, jobject obj,
                                                             jstring jpath) {
     return ToJString(env, GetRomMetadata(GetJString(env, jpath)).title);
@@ -87,8 +118,8 @@ jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getDeveloper(JNIEnv* env, job
 }
 
 jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getVersion(JNIEnv* env, jobject obj,
-                                                              jstring jpath) {
-    return ToJString(env, GetRomMetadata(GetJString(env, jpath)).version);
+                                                              jstring jpath, jboolean jreload) {
+    return ToJString(env, GetRomMetadata(GetJString(env, jpath), jreload).version);
 }
 
 jbyteArray Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIcon(JNIEnv* env, jobject obj,
@@ -106,7 +137,7 @@ jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsHomebrew(JNIEnv* env, j
 }
 
 void Java_org_yuzu_yuzu_1emu_utils_GameMetadata_resetMetadata(JNIEnv* env, jobject obj) {
-    return m_rom_metadata_cache.clear();
+    m_rom_metadata_cache.clear();
 }
 
 } // extern "C"

+ 10 - 1
src/android/app/src/main/jni/native.cpp

@@ -80,7 +80,7 @@ Core::System& EmulationSession::System() {
     return m_system;
 }
 
-FileSys::ManualContentProvider* EmulationSession::ContentProvider() {
+FileSys::ManualContentProvider* EmulationSession::GetContentProvider() {
     return m_manual_provider.get();
 }
 
@@ -880,4 +880,13 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getSavePath(JNIEnv* env, jobject j
     return ToJString(env, user_save_data_path);
 }
 
+void Java_org_yuzu_yuzu_1emu_NativeLibrary_addFileToFilesystemProvider(JNIEnv* env, jobject jobj,
+                                                                       jstring jpath) {
+    EmulationSession::GetInstance().ConfigureFilesystemProvider(GetJString(env, jpath));
+}
+
+void Java_org_yuzu_yuzu_1emu_NativeLibrary_clearFilesystemProvider(JNIEnv* env, jobject jobj) {
+    EmulationSession::GetInstance().GetContentProvider()->ClearAllEntries();
+}
+
 } // extern "C"

+ 1 - 0
src/android/app/src/main/jni/native.h

@@ -21,6 +21,7 @@ public:
     static EmulationSession& GetInstance();
     const Core::System& System() const;
     Core::System& System();
+    FileSys::ManualContentProvider* GetContentProvider();
 
     const EmuWindow_Android& Window() const;
     EmuWindow_Android& Window();