From e842d395fa156862915dfb47fddf879cb6ea3dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 11 Sep 2021 16:36:35 +0200 Subject: [PATCH] Add untested function Android_ComputeRecursiveDirectorySize --- Common/File/AndroidStorage.cpp | 13 +++++ Common/File/AndroidStorage.h | 2 + UI/GameInfoCache.cpp | 2 - .../src/org/ppsspp/ppsspp/PpssppActivity.java | 54 +++++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/Common/File/AndroidStorage.cpp b/Common/File/AndroidStorage.cpp index 78d457aabf..c98a649385 100644 --- a/Common/File/AndroidStorage.cpp +++ b/Common/File/AndroidStorage.cpp @@ -20,6 +20,7 @@ static jmethodID contentUriFileExists; static jmethodID contentUriGetFreeStorageSpace; static jmethodID filePathGetFreeStorageSpace; static jmethodID isExternalStoragePreservedLegacy; +static jmethodID computeRecursiveDirectorySize; static jobject g_nativeActivity; @@ -54,6 +55,8 @@ void Android_RegisterStorageCallbacks(JNIEnv * env, jobject obj) { _dbg_assert_(filePathGetFreeStorageSpace); isExternalStoragePreservedLegacy = env->GetMethodID(env->GetObjectClass(obj), "isExternalStoragePreservedLegacy", "()Z"); _dbg_assert_(isExternalStoragePreservedLegacy); + computeRecursiveDirectorySize = env->GetMethodID(env->GetObjectClass(obj), "computeRecursiveDirectorySize", "(Ljava/lang/String;)J"); + _dbg_assert_(computeRecursiveDirectorySize); } bool Android_IsContentUri(const std::string &filename) { @@ -258,6 +261,16 @@ int64_t Android_GetFreeSpaceByFilePath(const std::string &filePath) { return env->CallLongMethod(g_nativeActivity, filePathGetFreeStorageSpace, param); } +int64_t Android_ComputeRecursiveDirectorySize(const std::string &uri) { + if (!g_nativeActivity) { + return false; + } + auto env = getEnv(); + + jstring param = env->NewStringUTF(uri.c_str()); + return env->CallLongMethod(g_nativeActivity, computeRecursiveDirectorySize, param); +} + bool Android_IsExternalStoragePreservedLegacy() { if (!g_nativeActivity) { return false; diff --git a/Common/File/AndroidStorage.h b/Common/File/AndroidStorage.h index 2a890d33b4..40ab19f1b0 100644 --- a/Common/File/AndroidStorage.h +++ b/Common/File/AndroidStorage.h @@ -49,6 +49,7 @@ StorageError Android_RemoveFile(const std::string &fileUri); StorageError 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_ComputeRecursiveDirectorySize(const std::string &fileUri); int64_t Android_GetFreeSpaceByContentUri(const std::string &uri); int64_t Android_GetFreeSpaceByFilePath(const std::string &filePath); bool Android_IsExternalStoragePreservedLegacy(); @@ -72,6 +73,7 @@ inline StorageError Android_RemoveFile(const std::string &fileUri) { return Stor inline StorageError Android_RenameFileTo(const std::string &fileUri, const std::string &newName) { return StorageError::UNKNOWN; } 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_GetRecursiveDirectorySize(const std::string &fileUri) { return -1; } inline int64_t Android_GetFreeSpaceByContentUri(const std::string &uri) { return -1; } inline int64_t Android_GetFreeSpaceByFilePath(const std::string &filePath) { return -1; } inline bool Android_IsExternalStoragePreservedLegacy() { return false; } diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 803315aa77..25c426f5dd 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -343,13 +343,11 @@ public: void Run() override { // An early-return will result in the destructor running, where we can set // flags like working and pending. - if (!info_->LoadFromPath(gamePath_)) { return; } // In case of a remote file, check if it actually exists before locking. - // This is likely not necessary at a if (!info_->GetFileLoader()->Exists()) { return; } diff --git a/android/src/org/ppsspp/ppsspp/PpssppActivity.java b/android/src/org/ppsspp/ppsspp/PpssppActivity.java index 9f55c799cc..67b74014b0 100644 --- a/android/src/org/ppsspp/ppsspp/PpssppActivity.java +++ b/android/src/org/ppsspp/ppsspp/PpssppActivity.java @@ -178,6 +178,60 @@ public class PpssppActivity extends NativeActivity { return str + size + "|" + documentName + "|" + lastModified; } + private long directorySizeRecursion(Uri uri, String documentId) { + Cursor c = null; + try { + Log.i(TAG, "recursing into " + uri.toString()); + final String[] columns = new String[]{ + DocumentsContract.Document.COLUMN_DOCUMENT_ID, + DocumentsContract.Document.COLUMN_SIZE, + DocumentsContract.Document.COLUMN_MIME_TYPE, // check for MIME_TYPE_DIR + }; + final ContentResolver resolver = getContentResolver(); + final Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri, documentId); + c = resolver.query(childrenUri, columns, null, null, null); + long sizeSum = 0; + while (c.moveToNext()) { + final String mimeType = c.getString(2); + final boolean isDirectory = mimeType.equals(DocumentsContract.Document.MIME_TYPE_DIR); + if (isDirectory) { + final String childDocumentId = c.getString(0); + long dirSize = directorySizeRecursion( + DocumentsContract.buildDocumentUriUsingTree(uri, childDocumentId), + documentId + ); + if (dirSize >= 0) { + sizeSum += dirSize; + } + } else { + final long fileSize = c.getLong(1); + sizeSum += fileSize; + } + } + return sizeSum; + } catch (Exception e) { + return -1; + } finally { + if (c != null) { + c.close(); + } + } + } + + public long computeRecursiveDirectorySize(String uriString) { + try { + Uri uri = Uri.parse(uriString); + String documentId = DocumentsContract.getDocumentId(uri); + long totalSize = directorySizeRecursion(uri, documentId); + Log.i(TAG, "directorySizeRecursion(" + uriString + ") returned " + totalSize); + return totalSize; + } + catch (Exception e) { + Log.e(TAG, "computeRecursiveSize exception: " + e.toString()); + return -1; + } + } + // 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