Added an actual implementation for yes/no dialogs on Android using Object.wait and Object.notify.

Modified NativeLibrary to display alerts in AlertDialogs rather than Toast notifications, and allow yes/no options.
Modified MainAndroid to use the new displayAlertMsg, and to return its output.
This commit is contained in:
34will 2018-01-07 22:30:28 +00:00
parent dc08b73db1
commit 10ea9e5f5b
2 changed files with 79 additions and 9 deletions

View File

@ -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)

View File

@ -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