From 4f10ff9d31c672afcb1911b4f827b30bfb3ccd33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 18 Jul 2021 23:06:14 +0200 Subject: [PATCH] Add quick method to check file existence by content URI. Seems to speed up bringing up the pause screen slightly (checking for save state files). --- Common/File/AndroidStorage.cpp | 13 +++++++++++ Common/File/AndroidStorage.h | 4 +++- Common/File/FileUtil.cpp | 6 +---- .../src/org/ppsspp/ppsspp/PpssppActivity.java | 22 +++++++++++++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Common/File/AndroidStorage.cpp b/Common/File/AndroidStorage.cpp index 6c4cbbd60d..63a3438ed3 100644 --- a/Common/File/AndroidStorage.cpp +++ b/Common/File/AndroidStorage.cpp @@ -14,6 +14,7 @@ static jmethodID contentUriCreateDirectory; static jmethodID contentUriRemoveFile; static jmethodID contentUriRenameFileTo; static jmethodID contentUriGetFileInfo; +static jmethodID contentUriFileExists; static jmethodID contentUriGetFreeStorageSpace; static jmethodID filePathGetFreeStorageSpace; @@ -38,6 +39,8 @@ void Android_RegisterStorageCallbacks(JNIEnv * env, jobject obj) { _dbg_assert_(contentUriRenameFileTo); contentUriGetFileInfo = env->GetMethodID(env->GetObjectClass(obj), "contentUriGetFileInfo", "(Ljava/lang/String;)Ljava/lang/String;"); _dbg_assert_(contentUriGetFileInfo); + contentUriFileExists = env->GetMethodID(env->GetObjectClass(obj), "contentUriFileExists", "(Ljava/lang/String;)Z"); + _dbg_assert_(contentUriFileExists); contentUriGetFreeStorageSpace = env->GetMethodID(env->GetObjectClass(obj), "contentUriGetFreeStorageSpace", "(Ljava/lang/String;)J"); _dbg_assert_(contentUriGetFreeStorageSpace); filePathGetFreeStorageSpace = env->GetMethodID(env->GetObjectClass(obj), "filePathGetFreeStorageSpace", "(Ljava/lang/String;)J"); @@ -156,6 +159,16 @@ bool Android_GetFileInfo(const std::string &fileUri, File::FileInfo *fileInfo) { return retval && fileInfo->exists; } +bool Android_FileExists(const std::string &fileUri) { + if (!g_nativeActivity) { + return false; + } + auto env = getEnv(); + jstring paramFileUri = env->NewStringUTF(fileUri.c_str()); + bool exists = env->CallBooleanMethod(g_nativeActivity, contentUriFileExists, paramFileUri); + return exists; +} + std::vector Android_ListContentUri(const std::string &path) { if (!g_nativeActivity) { return std::vector(); diff --git a/Common/File/AndroidStorage.h b/Common/File/AndroidStorage.h index 89c4442bf8..5370cb2be2 100644 --- a/Common/File/AndroidStorage.h +++ b/Common/File/AndroidStorage.h @@ -28,6 +28,7 @@ bool Android_CreateFile(const std::string &parentTreeUri, const std::string &fil bool Android_RemoveFile(const std::string &fileUri); bool Android_RenameFileTo(const std::string &fileUri, const std::string &newName); bool Android_GetFileInfo(const std::string &fileUri, File::FileInfo *info); +bool Android_FileExists(const std::string &fileUri); int64_t Android_GetFreeSpaceByContentUri(const std::string &uri); int64_t Android_GetFreeSpaceByFilePath(const std::string &filePath); @@ -44,8 +45,9 @@ inline int Android_OpenContentUriFd(const std::string &uri, const Android_OpenCo inline bool Android_CreateDirectory(const std::string &parentTreeUri, const std::string &dirName) { return false; } inline bool Android_CreateFile(const std::string &parentTreeUri, const std::string &fileName) { return false; } inline bool Android_RemoveFile(const std::string &fileUri) { return false; } -inline bool Android_GetFileInfo(const std::string &fileUri, File::FileInfo *info) { return false; } inline bool Android_RenameFileTo(const std::string &fileUri, const std::string &newName) { return false; } +inline bool Android_GetFileInfo(const std::string &fileUri, File::FileInfo *info) { return false; } +inline bool Android_FileExists(const std::string &fileUri) { return false; } inline int64_t Android_GetFreeSpaceByContentUri(const std::string &uri) { return -1; } inline int64_t Android_GetFreeSpaceByFilePath(const std::string &filePath) { return -1; } inline std::vector Android_ListContentUri(const std::string &uri) { diff --git a/Common/File/FileUtil.cpp b/Common/File/FileUtil.cpp index 7a35ded386..88db815f7f 100644 --- a/Common/File/FileUtil.cpp +++ b/Common/File/FileUtil.cpp @@ -278,11 +278,7 @@ bool ExistsInDir(const Path &path, const std::string &filename) { bool Exists(const Path &path) { if (path.Type() == PathType::CONTENT_URI) { - FileInfo info; - if (!Android_GetFileInfo(path.c_str(), &info)) { - return false; - } - return info.exists; + return Android_FileExists(path.c_str()); } #if defined(_WIN32) diff --git a/android/src/org/ppsspp/ppsspp/PpssppActivity.java b/android/src/org/ppsspp/ppsspp/PpssppActivity.java index a35da130e8..7d7ad42489 100644 --- a/android/src/org/ppsspp/ppsspp/PpssppActivity.java +++ b/android/src/org/ppsspp/ppsspp/PpssppActivity.java @@ -149,6 +149,8 @@ public class PpssppActivity extends NativeActivity { } // TODO: Maybe add a cheaper version that doesn't extract all the file information? + // TODO: Replace with a proper query: + // * https://stackoverflow.com/questions/42186820/documentfile-is-very-slow public String[] listContentUriDir(String uriString) { try { Uri uri = Uri.parse(uriString); @@ -235,6 +237,26 @@ public class PpssppActivity extends NativeActivity { } } + // Possibly faster than contentUriGetFileInfo. + public boolean contentUriFileExists(String fileUri) { + try { + Uri uri = Uri.parse(fileUri); + DocumentFile documentFile = DocumentFile.fromSingleUri(this, uri); + if (documentFile != null) { + if (documentFile.exists()) { + return true; + } else { + return false; + } + } else { + return false; + } + } catch (Exception e) { + Log.e(TAG, "contentUriFileExists exception: " + e.toString()); + return false; + } + } + public String contentUriGetFileInfo(String fileName) { try { Uri uri = Uri.parse(fileName);