From b38ff54af62c8bbf96fe22cbd97d5bbec6ba7b68 Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Mon, 31 Aug 2020 22:32:17 +0800 Subject: [PATCH] android: Use DialogFragment for the core error dialog Fixes a bug when changing orientation while the dialog is shown. --- .../org/citra/citra_emu/NativeLibrary.java | 89 +++++++++++++------ 1 file changed, 63 insertions(+), 26 deletions(-) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java index 01e5aca95..48555252e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java +++ b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.java @@ -6,8 +6,11 @@ package org.citra.citra_emu; +import android.app.Activity; +import android.app.Dialog; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.os.Bundle; import android.text.Html; import android.text.method.LinkMovementMethod; import android.view.Surface; @@ -16,17 +19,21 @@ import android.widget.EditText; import android.widget.FrameLayout; import android.widget.TextView; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; +import androidx.fragment.app.DialogFragment; import org.citra.citra_emu.activities.EmulationActivity; +import org.citra.citra_emu.applets.SoftwareKeyboard; import org.citra.citra_emu.utils.EmulationMenuSettings; import org.citra.citra_emu.utils.Log; import org.citra.citra_emu.utils.PermissionsHandler; import java.lang.ref.WeakReference; import java.util.Date; +import java.util.Objects; import static android.Manifest.permission.CAMERA; import static android.Manifest.permission.RECORD_AUDIO; @@ -218,6 +225,59 @@ public final class NativeLibrary { } private static boolean coreErrorAlertResult = false; + private static final Object coreErrorAlertLock = new Object(); + + public static class CoreErrorDialogFragment extends DialogFragment { + static CoreErrorDialogFragment newInstance(String title, String message) { + CoreErrorDialogFragment frag = new CoreErrorDialogFragment(); + Bundle args = new Bundle(); + args.putString("title", title); + args.putString("message", message); + frag.setArguments(args); + return frag; + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + final Activity emulationActivity = Objects.requireNonNull(getActivity()); + + final String title = Objects.requireNonNull(Objects.requireNonNull(getArguments()).getString("title")); + final String message = Objects.requireNonNull(Objects.requireNonNull(getArguments()).getString("message")); + + return new AlertDialog.Builder(emulationActivity) + .setTitle(title) + .setMessage(message) + .setPositiveButton(R.string.continue_button, (dialog, which) -> { + coreErrorAlertResult = true; + synchronized (coreErrorAlertLock) { + coreErrorAlertLock.notify(); + } + }) + .setNegativeButton(R.string.abort_button, (dialog, which) -> { + coreErrorAlertResult = false; + synchronized (coreErrorAlertLock) { + coreErrorAlertLock.notify(); + } + }).setOnDismissListener(dialog -> { + coreErrorAlertResult = true; + synchronized (coreErrorAlertLock) { + coreErrorAlertLock.notify(); + } + }).create(); + } + } + + private static void OnCoreErrorImpl(String title, String message) { + final EmulationActivity emulationActivity = sEmulationActivity.get(); + if (emulationActivity == null) { + Log.error("[NativeLibrary] EmulationActivity not present"); + return; + } + + CoreErrorDialogFragment fragment = CoreErrorDialogFragment.newInstance(title, message); + fragment.show(emulationActivity.getSupportFragmentManager(), "coreError"); + } /** * Handles a core error. @@ -252,36 +312,13 @@ public final class NativeLibrary { } } - // Create object used for waiting. - final Object lock = new Object(); - final AlertDialog.Builder builder = new AlertDialog.Builder(emulationActivity) - .setTitle(title) - .setMessage(message) - .setPositiveButton(R.string.continue_button, (dialog, which) -> { - coreErrorAlertResult = true; - synchronized (lock) { - lock.notify(); - } - }) - .setNegativeButton(R.string.abort_button, (dialog, which) -> { - coreErrorAlertResult = false; - synchronized (lock) { - lock.notify(); - } - }).setOnDismissListener(dialog -> { - coreErrorAlertResult = true; - synchronized (lock) { - lock.notify(); - } - }); - // Show the AlertDialog on the main thread. - emulationActivity.runOnUiThread(builder::show); + emulationActivity.runOnUiThread(() -> OnCoreErrorImpl(title, message)); // Wait for the lock to notify that it is complete. - synchronized (lock) { + synchronized (coreErrorAlertLock) { try { - lock.wait(); + coreErrorAlertLock.wait(); } catch (Exception ignored) { } }