From e10d89cfbcaedbb4734537d44826e055cd8ae9db Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 2 Apr 2013 07:57:37 -0700 Subject: [PATCH] Fixed bug 1780 - SDL_RWFromFile() sets an error on Android although a valid SDL_RWops pointer is returned. Philipp Wiesemann SDL_RWFromFile() sets an error to be queried with SDL_GetError() on Android although a valid SDL_RWops pointer is returned. This happens if the fallback implemented in SDL_android.cpp is used to load compressed assets (see README.android in section "Loading assets") and results in a message like "java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed". I think this is confusing and not needed because the loading works as expected. I attached a patch which changes SDL_android.cpp to not set an error if compressed assets are loaded. In this case also no Exception is queried and no additional string are created. --- src/core/android/SDL_android.cpp | 42 +++++++++++++++++--------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/core/android/SDL_android.cpp b/src/core/android/SDL_android.cpp index 457512a16..5ae8f93a0 100644 --- a/src/core/android/SDL_android.cpp +++ b/src/core/android/SDL_android.cpp @@ -509,7 +509,8 @@ extern "C" void Android_JNI_CloseAudioDevice() } // Test for an exception and call SDL_SetError with its detail if one occurs -static bool Android_JNI_ExceptionOccurred() +// If optional parameter silent is truthy then SDL_SetError() is not called. +static bool Android_JNI_ExceptionOccurred(bool silent = false) { SDL_assert(LocalReferenceHolder::IsActive()); JNIEnv *mEnv = Android_JNI_GetEnv(); @@ -521,26 +522,27 @@ static bool Android_JNI_ExceptionOccurred() // Until this happens most JNI operations have undefined behaviour mEnv->ExceptionClear(); - jclass exceptionClass = mEnv->GetObjectClass(exception); - jclass classClass = mEnv->FindClass("java/lang/Class"); + if (!silent) { + jclass exceptionClass = mEnv->GetObjectClass(exception); + jclass classClass = mEnv->FindClass("java/lang/Class"); - mid = mEnv->GetMethodID(classClass, "getName", "()Ljava/lang/String;"); - jstring exceptionName = (jstring)mEnv->CallObjectMethod(exceptionClass, mid); - const char* exceptionNameUTF8 = mEnv->GetStringUTFChars(exceptionName, 0); + mid = mEnv->GetMethodID(classClass, "getName", "()Ljava/lang/String;"); + jstring exceptionName = (jstring)mEnv->CallObjectMethod(exceptionClass, mid); + const char* exceptionNameUTF8 = mEnv->GetStringUTFChars(exceptionName, 0); - mid = mEnv->GetMethodID(exceptionClass, "getMessage", "()Ljava/lang/String;"); - jstring exceptionMessage = (jstring)mEnv->CallObjectMethod(exception, mid); + mid = mEnv->GetMethodID(exceptionClass, "getMessage", "()Ljava/lang/String;"); + jstring exceptionMessage = (jstring)mEnv->CallObjectMethod(exception, mid); - if (exceptionMessage != NULL) { - const char* exceptionMessageUTF8 = mEnv->GetStringUTFChars( - exceptionMessage, 0); - SDL_SetError("%s: %s", exceptionNameUTF8, exceptionMessageUTF8); - mEnv->ReleaseStringUTFChars(exceptionMessage, exceptionMessageUTF8); - } else { - SDL_SetError("%s", exceptionNameUTF8); - } + if (exceptionMessage != NULL) { + const char* exceptionMessageUTF8 = mEnv->GetStringUTFChars(exceptionMessage, 0); + SDL_SetError("%s: %s", exceptionNameUTF8, exceptionMessageUTF8); + mEnv->ReleaseStringUTFChars(exceptionMessage, exceptionMessageUTF8); + } else { + SDL_SetError("%s", exceptionNameUTF8); + } - mEnv->ReleaseStringUTFChars(exceptionName, exceptionNameUTF8); + mEnv->ReleaseStringUTFChars(exceptionName, exceptionNameUTF8); + } return true; } @@ -588,19 +590,19 @@ static int Android_JNI_FileOpen(SDL_RWops* ctx) */ mid = mEnv->GetMethodID(mEnv->GetObjectClass(assetManager), "openFd", "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;"); inputStream = mEnv->CallObjectMethod(assetManager, mid, fileNameJString); - if (Android_JNI_ExceptionOccurred()) { + if (Android_JNI_ExceptionOccurred(true)) { goto fallback; } mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getStartOffset", "()J"); ctx->hidden.androidio.offset = mEnv->CallLongMethod(inputStream, mid); - if (Android_JNI_ExceptionOccurred()) { + if (Android_JNI_ExceptionOccurred(true)) { goto fallback; } mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getDeclaredLength", "()J"); ctx->hidden.androidio.size = mEnv->CallLongMethod(inputStream, mid); - if (Android_JNI_ExceptionOccurred()) { + if (Android_JNI_ExceptionOccurred(true)) { goto fallback; }