src/core/android/SDL_android.cpp
changeset 7045 4be2c24b7de1
parent 7039 f69b305b053d
child 7083 0cb47cc139d3
equal deleted inserted replaced
7044:30b7b0f09c51 7045:4be2c24b7de1
   507         audioBufferPinned = NULL;
   507         audioBufferPinned = NULL;
   508     }
   508     }
   509 }
   509 }
   510 
   510 
   511 // Test for an exception and call SDL_SetError with its detail if one occurs
   511 // Test for an exception and call SDL_SetError with its detail if one occurs
   512 static bool Android_JNI_ExceptionOccurred()
   512 // If optional parameter silent is truthy then SDL_SetError() is not called.
       
   513 static bool Android_JNI_ExceptionOccurred(bool silent = false)
   513 {
   514 {
   514     SDL_assert(LocalReferenceHolder::IsActive());
   515     SDL_assert(LocalReferenceHolder::IsActive());
   515     JNIEnv *mEnv = Android_JNI_GetEnv();
   516     JNIEnv *mEnv = Android_JNI_GetEnv();
   516 
   517 
   517     jthrowable exception = mEnv->ExceptionOccurred();
   518     jthrowable exception = mEnv->ExceptionOccurred();
   519         jmethodID mid;
   520         jmethodID mid;
   520 
   521 
   521         // Until this happens most JNI operations have undefined behaviour
   522         // Until this happens most JNI operations have undefined behaviour
   522         mEnv->ExceptionClear();
   523         mEnv->ExceptionClear();
   523 
   524 
   524         jclass exceptionClass = mEnv->GetObjectClass(exception);
   525         if (!silent) {
   525         jclass classClass = mEnv->FindClass("java/lang/Class");
   526             jclass exceptionClass = mEnv->GetObjectClass(exception);
   526 
   527             jclass classClass = mEnv->FindClass("java/lang/Class");
   527         mid = mEnv->GetMethodID(classClass, "getName", "()Ljava/lang/String;");
   528 
   528         jstring exceptionName = (jstring)mEnv->CallObjectMethod(exceptionClass, mid);
   529             mid = mEnv->GetMethodID(classClass, "getName", "()Ljava/lang/String;");
   529         const char* exceptionNameUTF8 = mEnv->GetStringUTFChars(exceptionName, 0);
   530             jstring exceptionName = (jstring)mEnv->CallObjectMethod(exceptionClass, mid);
   530 
   531             const char* exceptionNameUTF8 = mEnv->GetStringUTFChars(exceptionName, 0);
   531         mid = mEnv->GetMethodID(exceptionClass, "getMessage", "()Ljava/lang/String;");
   532 
   532         jstring exceptionMessage = (jstring)mEnv->CallObjectMethod(exception, mid);
   533             mid = mEnv->GetMethodID(exceptionClass, "getMessage", "()Ljava/lang/String;");
   533 
   534             jstring exceptionMessage = (jstring)mEnv->CallObjectMethod(exception, mid);
   534         if (exceptionMessage != NULL) {
   535 
   535             const char* exceptionMessageUTF8 = mEnv->GetStringUTFChars(
   536             if (exceptionMessage != NULL) {
   536                     exceptionMessage, 0);
   537                 const char* exceptionMessageUTF8 = mEnv->GetStringUTFChars(exceptionMessage, 0);
   537             SDL_SetError("%s: %s", exceptionNameUTF8, exceptionMessageUTF8);
   538                 SDL_SetError("%s: %s", exceptionNameUTF8, exceptionMessageUTF8);
   538             mEnv->ReleaseStringUTFChars(exceptionMessage, exceptionMessageUTF8);
   539                 mEnv->ReleaseStringUTFChars(exceptionMessage, exceptionMessageUTF8);
   539         } else {
   540             } else {
   540             SDL_SetError("%s", exceptionNameUTF8);
   541                 SDL_SetError("%s", exceptionNameUTF8);
   541         }
   542             }
   542 
   543 
   543         mEnv->ReleaseStringUTFChars(exceptionName, exceptionNameUTF8);
   544             mEnv->ReleaseStringUTFChars(exceptionName, exceptionNameUTF8);
       
   545         }
   544 
   546 
   545         return true;
   547         return true;
   546     }
   548     }
   547 
   549 
   548     return false;
   550     return false;
   586     /* First let's try opening the file to obtain an AssetFileDescriptor.
   588     /* First let's try opening the file to obtain an AssetFileDescriptor.
   587     * This method reads the files directly from the APKs using standard *nix calls
   589     * This method reads the files directly from the APKs using standard *nix calls
   588     */
   590     */
   589     mid = mEnv->GetMethodID(mEnv->GetObjectClass(assetManager), "openFd", "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;");
   591     mid = mEnv->GetMethodID(mEnv->GetObjectClass(assetManager), "openFd", "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;");
   590     inputStream = mEnv->CallObjectMethod(assetManager, mid, fileNameJString);
   592     inputStream = mEnv->CallObjectMethod(assetManager, mid, fileNameJString);
   591     if (Android_JNI_ExceptionOccurred()) {
   593     if (Android_JNI_ExceptionOccurred(true)) {
   592         goto fallback;
   594         goto fallback;
   593     }
   595     }
   594 
   596 
   595     mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getStartOffset", "()J");
   597     mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getStartOffset", "()J");
   596     ctx->hidden.androidio.offset = mEnv->CallLongMethod(inputStream, mid);
   598     ctx->hidden.androidio.offset = mEnv->CallLongMethod(inputStream, mid);
   597     if (Android_JNI_ExceptionOccurred()) {
   599     if (Android_JNI_ExceptionOccurred(true)) {
   598         goto fallback;
   600         goto fallback;
   599     }
   601     }
   600 
   602 
   601     mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getDeclaredLength", "()J");
   603     mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getDeclaredLength", "()J");
   602     ctx->hidden.androidio.size = mEnv->CallLongMethod(inputStream, mid);
   604     ctx->hidden.androidio.size = mEnv->CallLongMethod(inputStream, mid);
   603     if (Android_JNI_ExceptionOccurred()) {
   605     if (Android_JNI_ExceptionOccurred(true)) {
   604         goto fallback;
   606         goto fallback;
   605     }
   607     }
   606 
   608 
   607     mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getFileDescriptor", "()Ljava/io/FileDescriptor;");
   609     mid = mEnv->GetMethodID(mEnv->GetObjectClass(inputStream), "getFileDescriptor", "()Ljava/io/FileDescriptor;");
   608     fd = mEnv->CallObjectMethod(inputStream, mid);
   610     fd = mEnv->CallObjectMethod(inputStream, mid);