diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java index e82de7fa01..d7e0e50f00 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -6,6 +6,11 @@ package org.dolphinemu.dolphinemu; +import android.app.AlertDialog; +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.view.Surface; import android.widget.Toast; @@ -401,18 +406,81 @@ public final class NativeLibrary CacheClassesAndMethods(); } - public static void displayAlertMsg(final String alert) + private static boolean alertResult = false; + public static boolean displayAlertMsg(final String caption, final String text, final boolean yesNo) { - Log.error("[NativeLibrary] Alert: " + alert); + Log.error("[NativeLibrary] Alert: " + text); final EmulationActivity emulationActivity = sEmulationActivity.get(); - if (emulationActivity != null) + boolean result = false; + if (emulationActivity == null) { - emulationActivity.runOnUiThread(() -> Toast.makeText(emulationActivity, "Panic Alert: " + alert, Toast.LENGTH_LONG).show()); + Log.warning("[NativeLibrary] EmulationActivity is null, can't do panic alert."); } else { - Log.warning("[NativeLibrary] EmulationActivity is null, can't do panic toast."); + // Create object used for waiting. + final Object lock = new Object(); + AlertDialog.Builder builder = new AlertDialog.Builder(emulationActivity) + .setTitle(caption) + .setMessage(text); + + // If not yes/no dialog just have one button that dismisses modal, + // otherwise have a yes and no button that sets alertResult accordingly. + if (!yesNo) + { + builder + .setCancelable(false) + .setPositiveButton("OK", (dialog, whichButton) -> + { + dialog.dismiss(); + synchronized (lock) + { + lock.notify(); + } + }); + } + else + { + alertResult = false; + + builder + .setPositiveButton("Yes", (dialog, whichButton) -> + { + alertResult = true; + dialog.dismiss(); + synchronized (lock) + { + lock.notify(); + } + }) + .setNegativeButton("No", (dialog, whichButton) -> + { + alertResult = false; + dialog.dismiss(); + synchronized (lock) + { + lock.notify(); + } + }); + } + + // Show the AlertDialog on the main thread. + emulationActivity.runOnUiThread(() -> builder.show()); + + // Wait for the lock to notify that it is complete. + synchronized (lock) + { + try + { + lock.wait(); + } + catch (Exception e) { } + } + + if (yesNo) + result = alertResult; } + return result; } public static void setEmulationActivity(EmulationActivity emulationActivity) diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 56523d9eb4..85cea2092a 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -161,12 +161,14 @@ static bool MsgAlert(const char* caption, const char* text, bool yes_no, MsgType g_java_vm->AttachCurrentThread(&env, NULL); // Execute the Java method. - env->CallStaticVoidMethod(s_jni_class, s_jni_method_alert, env->NewStringUTF(text)); + jboolean result = + env->CallStaticBooleanMethod(s_jni_class, s_jni_method_alert, env->NewStringUTF(caption), + env->NewStringUTF(text), yes_no ? JNI_TRUE : JNI_FALSE); // Must be called before the current thread exits; might as well do it here. g_java_vm->DetachCurrentThread(); - return false; + return result != JNI_FALSE; } #define DVD_BANNER_WIDTH 96 @@ -767,8 +769,8 @@ Java_org_dolphinemu_dolphinemu_NativeLibrary_CacheClassesAndMethods(JNIEnv* env, // Method signature taken from javap -s // Source/Android/app/build/intermediates/classes/arm/debug/org/dolphinemu/dolphinemu/NativeLibrary.class - s_jni_method_alert = - env->GetStaticMethodID(s_jni_class, "displayAlertMsg", "(Ljava/lang/String;)V"); + s_jni_method_alert = env->GetStaticMethodID(s_jni_class, "displayAlertMsg", + "(Ljava/lang/String;Ljava/lang/String;Z)Z"); } // Surface Handling