From 5384fa499869dbf655c6838eb6660138cf80cccc Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Thu, 15 Jun 2023 17:20:56 -0700
Subject: [PATCH] android: fs: Fix Exists / IsFile for SAF.

---
 .../java/org/yuzu/yuzu_emu/NativeLibrary.kt   | 18 +++++++++++++
 .../org/yuzu/yuzu_emu/utils/DocumentsTree.kt  |  5 ++++
 src/common/fs/fs.cpp                          | 27 +++++++++++++++++++
 src/common/fs/fs_android.h                    |  5 +++-
 4 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
index 22f0a26468..f3bfbe7eb4 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
@@ -19,6 +19,8 @@ import org.yuzu.yuzu_emu.activities.EmulationActivity
 import org.yuzu.yuzu_emu.utils.DocumentsTree.Companion.isNativePath
 import org.yuzu.yuzu_emu.utils.FileUtil.getFileSize
 import org.yuzu.yuzu_emu.utils.FileUtil.openContentUri
+import org.yuzu.yuzu_emu.utils.FileUtil.exists
+import org.yuzu.yuzu_emu.utils.FileUtil.isDirectory
 import org.yuzu.yuzu_emu.utils.Log.error
 import org.yuzu.yuzu_emu.utils.Log.verbose
 import org.yuzu.yuzu_emu.utils.Log.warning
@@ -85,6 +87,22 @@ object NativeLibrary {
         } else getFileSize(appContext, path)
     }
 
+    @Keep
+    @JvmStatic
+    fun exists(path: String?): Boolean {
+        return if (isNativePath(path!!)) {
+            YuzuApplication.documentsTree!!.exists(path)
+        } else exists(appContext, path)
+    }
+
+    @Keep
+    @JvmStatic
+    fun isDirectory(path: String?): Boolean {
+        return if (isNativePath(path!!)) {
+            YuzuApplication.documentsTree!!.isDirectory(path)
+        } else isDirectory(appContext, path)
+    }
+
     /**
      * Returns true if pro controller isn't available and handheld is
      */
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt
index cc8ea6b9d4..f8abae445f 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DocumentsTree.kt
@@ -36,6 +36,11 @@ class DocumentsTree {
         return resolvePath(filepath) != null
     }
 
+    fun isDirectory(filepath: String): Boolean {
+        val node = resolvePath(filepath)
+        return node != null && node.isDirectory
+    }
+
     private fun resolvePath(filepath: String): DocumentsNode? {
         val tokens = StringTokenizer(filepath, File.separator, false)
         var iterator = root
diff --git a/src/common/fs/fs.cpp b/src/common/fs/fs.cpp
index e1716c62de..6d66c926dc 100644
--- a/src/common/fs/fs.cpp
+++ b/src/common/fs/fs.cpp
@@ -3,6 +3,9 @@
 
 #include "common/fs/file.h"
 #include "common/fs/fs.h"
+#ifdef ANDROID
+#include "common/fs/fs_android.h"
+#endif
 #include "common/fs/path_util.h"
 #include "common/logging/log.h"
 
@@ -525,15 +528,39 @@ void IterateDirEntriesRecursively(const std::filesystem::path& path,
 // Generic Filesystem Operations
 
 bool Exists(const fs::path& path) {
+#ifdef ANDROID
+    if (Android::IsContentUri(path)) {
+        return Android::Exists(path);
+    } else {
+        return fs::exists(path);
+    }
+#else
     return fs::exists(path);
+#endif
 }
 
 bool IsFile(const fs::path& path) {
+#ifdef ANDROID
+    if (Android::IsContentUri(path)) {
+        return !Android::IsDirectory(path);
+    } else {
+        return fs::is_regular_file(path);
+    }
+#else
     return fs::is_regular_file(path);
+#endif
 }
 
 bool IsDir(const fs::path& path) {
+#ifdef ANDROID
+    if (Android::IsContentUri(path)) {
+        return Android::IsDirectory(path);
+    } else {
+        return fs::is_directory(path);
+    }
+#else
     return fs::is_directory(path);
+#endif
 }
 
 fs::path GetCurrentDir() {
diff --git a/src/common/fs/fs_android.h b/src/common/fs/fs_android.h
index bb8a526487..b441c2a128 100644
--- a/src/common/fs/fs_android.h
+++ b/src/common/fs/fs_android.h
@@ -12,7 +12,10 @@
       "openContentUri", "(Ljava/lang/String;Ljava/lang/String;)I")
 
 #define ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(V)                                                 \
-    V(GetSize, std::uint64_t, get_size, CallStaticLongMethod, "getSize", "(Ljava/lang/String;)J")
+    V(GetSize, std::uint64_t, get_size, CallStaticLongMethod, "getSize", "(Ljava/lang/String;)J")  \
+    V(IsDirectory, bool, is_directory, CallStaticBooleanMethod, "isDirectory",                     \
+      "(Ljava/lang/String;)Z")                                                                     \
+    V(Exists, bool, file_exists, CallStaticBooleanMethod, "exists", "(Ljava/lang/String;)Z")
 
 namespace Common::FS::Android {