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 d3fbcce9c0..53e950ac41 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 @@ -99,6 +99,12 @@ public class ContentHandler return -1; } + @Nullable @Keep + public static String getDisplayName(String uri) + { + return getDisplayName(Uri.parse(uri)); + } + @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 066b8edf27..373a4699cd 100644 --- a/Source/Android/jni/AndroidCommon/AndroidCommon.cpp +++ b/Source/Android/jni/AndroidCommon/AndroidCommon.cpp @@ -112,6 +112,15 @@ jlong GetAndroidContentSizeAndIsDirectory(const std::string& uri) ToJString(env, uri)); } +std::string GetAndroidContentDisplayName(const std::string& uri) +{ + JNIEnv* env = IDCache::GetEnvForThread(); + jobject display_name = + env->CallStaticObjectMethod(IDCache::GetContentHandlerClass(), + IDCache::GetContentHandlerGetDisplayName(), ToJString(env, uri)); + return display_name ? GetJString(env, reinterpret_cast(display_name)) : ""; +} + int GetNetworkIpAddress() { JNIEnv* env = IDCache::GetEnvForThread(); diff --git a/Source/Android/jni/AndroidCommon/AndroidCommon.h b/Source/Android/jni/AndroidCommon/AndroidCommon.h index 5502363c9c..cb14d493b9 100644 --- a/Source/Android/jni/AndroidCommon/AndroidCommon.h +++ b/Source/Android/jni/AndroidCommon/AndroidCommon.h @@ -28,6 +28,12 @@ bool DeleteAndroidContent(const std::string& uri); // Returns -1 if not found, -2 if directory, file size otherwise. jlong GetAndroidContentSizeAndIsDirectory(const std::string& uri); +// An unmangled URI (one which the C++ code has not appended anything to) can't be relied on +// to contain a file name at all. If a file name is desired, this function is the most reliable +// way to get it, but the display name is not guaranteed to always actually be like a file name. +// An empty string will be returned for files which do not exist. +std::string GetAndroidContentDisplayName(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 5f5503eb87..baf44633f7 100644 --- a/Source/Android/jni/AndroidCommon/IDCache.cpp +++ b/Source/Android/jni/AndroidCommon/IDCache.cpp @@ -45,6 +45,7 @@ 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 jmethodID s_content_handler_get_display_name; static jclass s_network_helper_class; static jmethodID s_network_helper_get_network_ip_address; @@ -216,6 +217,11 @@ jmethodID GetContentHandlerGetSizeAndIsDirectory() return s_content_handler_get_size_and_is_directory; } +jmethodID GetContentHandlerGetDisplayName() +{ + return s_content_handler_get_display_name; +} + jclass GetNetworkHelperClass() { return s_network_helper_class; @@ -315,6 +321,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) 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"); + s_content_handler_get_display_name = env->GetStaticMethodID( + s_content_handler_class, "getDisplayName", "(Ljava/lang/String;)Ljava/lang/String;"); 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 2a6c9ccbb8..621a522a6c 100644 --- a/Source/Android/jni/AndroidCommon/IDCache.h +++ b/Source/Android/jni/AndroidCommon/IDCache.h @@ -45,6 +45,7 @@ jclass GetContentHandlerClass(); jmethodID GetContentHandlerOpenFd(); jmethodID GetContentHandlerDelete(); jmethodID GetContentHandlerGetSizeAndIsDirectory(); +jmethodID GetContentHandlerGetDisplayName(); jclass GetNetworkHelperClass(); jmethodID GetNetworkHelperGetNetworkIpAddress(); diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 6a8a4461f8..cb1e795a1c 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -158,6 +158,15 @@ BootParameters::GenerateFromFile(std::vector paths, if (paths.size() == 1) paths.clear(); +#ifdef ANDROID + if (extension.empty() && IsPathAndroidContent(path)) + { + const std::string display_name = GetAndroidContentDisplayName(path); + SplitPath(display_name, nullptr, nullptr, &extension); + std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); + } +#endif + static const std::unordered_set disc_image_extensions = { {".gcm", ".iso", ".tgc", ".wbfs", ".ciso", ".gcz", ".wia", ".rvz", ".dol", ".elf"}}; if (disc_image_extensions.find(extension) != disc_image_extensions.end() || is_drive)