From a7c05d7e84df5949e8edf42fa6332d6aa58282f6 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Thu, 5 Nov 2020 19:47:23 +0100 Subject: Android: Add content provider support to File::FileInfo --- .../dolphinemu/utils/ContentHandler.java | 25 ++++++++++++++++++++++ Source/Android/jni/AndroidCommon/AndroidCommon.cpp | 8 +++++++ Source/Android/jni/AndroidCommon/AndroidCommon.h | 3 +++ Source/Android/jni/AndroidCommon/IDCache.cpp | 9 ++++++++ Source/Android/jni/AndroidCommon/IDCache.h | 1 + 5 files changed, 46 insertions(+) (limited to 'Source/Android') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ContentHandler.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ContentHandler.java index dbeb410079..d3fbcce9c0 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ContentHandler.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ContentHandler.java @@ -74,6 +74,31 @@ public class ContentHandler return false; } + /** + * @return -1 if not found, -2 if directory, file size otherwise + */ + @Keep + public static long getSizeAndIsDirectory(String uri) + { + final String[] projection = new String[]{Document.COLUMN_MIME_TYPE, Document.COLUMN_SIZE}; + try (Cursor cursor = getContentResolver().query(Uri.parse(uri), projection, null, null, null)) + { + if (cursor != null && cursor.moveToFirst()) + { + if (Document.MIME_TYPE_DIR.equals(cursor.getString(0))) + return -2; + else + return cursor.isNull(1) ? 0 : cursor.getLong(1); + } + } + catch (SecurityException e) + { + Log.error("Tried to get metadata for " + uri + " without permission"); + } + + return -1; + } + @Nullable public static String getDisplayName(@NonNull Uri uri) { diff --git a/Source/Android/jni/AndroidCommon/AndroidCommon.cpp b/Source/Android/jni/AndroidCommon/AndroidCommon.cpp index 2870044ac9..066b8edf27 100644 --- a/Source/Android/jni/AndroidCommon/AndroidCommon.cpp +++ b/Source/Android/jni/AndroidCommon/AndroidCommon.cpp @@ -104,6 +104,14 @@ bool DeleteAndroidContent(const std::string& uri) IDCache::GetContentHandlerDelete(), ToJString(env, uri)); } +jlong GetAndroidContentSizeAndIsDirectory(const std::string& uri) +{ + JNIEnv* env = IDCache::GetEnvForThread(); + return env->CallStaticLongMethod(IDCache::GetContentHandlerClass(), + IDCache::GetContentHandlerGetSizeAndIsDirectory(), + ToJString(env, uri)); +} + int GetNetworkIpAddress() { JNIEnv* env = IDCache::GetEnvForThread(); diff --git a/Source/Android/jni/AndroidCommon/AndroidCommon.h b/Source/Android/jni/AndroidCommon/AndroidCommon.h index a196108cfe..5502363c9c 100644 --- a/Source/Android/jni/AndroidCommon/AndroidCommon.h +++ b/Source/Android/jni/AndroidCommon/AndroidCommon.h @@ -25,6 +25,9 @@ int OpenAndroidContent(const std::string& uri, const std::string& mode); // Deletes a given file. bool DeleteAndroidContent(const std::string& uri); +// Returns -1 if not found, -2 if directory, file size otherwise. +jlong GetAndroidContentSizeAndIsDirectory(const std::string& uri); + int GetNetworkIpAddress(); int GetNetworkPrefixLength(); int GetNetworkGateway(); diff --git a/Source/Android/jni/AndroidCommon/IDCache.cpp b/Source/Android/jni/AndroidCommon/IDCache.cpp index 674233d79f..5f5503eb87 100644 --- a/Source/Android/jni/AndroidCommon/IDCache.cpp +++ b/Source/Android/jni/AndroidCommon/IDCache.cpp @@ -44,6 +44,7 @@ static jmethodID s_compress_cb_run; static jclass s_content_handler_class; static jmethodID s_content_handler_open_fd; static jmethodID s_content_handler_delete; +static jmethodID s_content_handler_get_size_and_is_directory; static jclass s_network_helper_class; static jmethodID s_network_helper_get_network_ip_address; @@ -210,6 +211,11 @@ jmethodID GetContentHandlerDelete() return s_content_handler_delete; } +jmethodID GetContentHandlerGetSizeAndIsDirectory() +{ + return s_content_handler_get_size_and_is_directory; +} + jclass GetNetworkHelperClass() { return s_network_helper_class; @@ -229,6 +235,7 @@ jmethodID GetNetworkHelperGetNetworkGateway() { return s_network_helper_get_network_gateway; } + } // namespace IDCache #ifdef __cplusplus @@ -306,6 +313,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) "(Ljava/lang/String;Ljava/lang/String;)I"); s_content_handler_delete = env->GetStaticMethodID(s_content_handler_class, "delete", "(Ljava/lang/String;)Z"); + s_content_handler_get_size_and_is_directory = env->GetStaticMethodID( + s_content_handler_class, "getSizeAndIsDirectory", "(Ljava/lang/String;)J"); const jclass network_helper_class = env->FindClass("org/dolphinemu/dolphinemu/utils/NetworkHelper"); diff --git a/Source/Android/jni/AndroidCommon/IDCache.h b/Source/Android/jni/AndroidCommon/IDCache.h index c89e0c9fcc..2a6c9ccbb8 100644 --- a/Source/Android/jni/AndroidCommon/IDCache.h +++ b/Source/Android/jni/AndroidCommon/IDCache.h @@ -44,6 +44,7 @@ jmethodID GetCompressCallbackRun(); jclass GetContentHandlerClass(); jmethodID GetContentHandlerOpenFd(); jmethodID GetContentHandlerDelete(); +jmethodID GetContentHandlerGetSizeAndIsDirectory(); jclass GetNetworkHelperClass(); jmethodID GetNetworkHelperGetNetworkIpAddress(); -- cgit v1.2.3