android: Use DialogFragment for the core error dialog

Fixes a bug when changing orientation while the dialog is shown.
This commit is contained in:
zhupengfei 2020-08-31 22:32:17 +08:00 committed by bunnei
parent a56eba77fb
commit b38ff54af6

View File

@ -6,8 +6,11 @@
package org.citra.citra_emu; package org.citra.citra_emu;
import android.app.Activity;
import android.app.Dialog;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Bundle;
import android.text.Html; import android.text.Html;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.view.Surface; import android.view.Surface;
@ -16,17 +19,21 @@ import android.widget.EditText;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.fragment.app.DialogFragment;
import org.citra.citra_emu.activities.EmulationActivity; 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.EmulationMenuSettings;
import org.citra.citra_emu.utils.Log; import org.citra.citra_emu.utils.Log;
import org.citra.citra_emu.utils.PermissionsHandler; import org.citra.citra_emu.utils.PermissionsHandler;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Date; import java.util.Date;
import java.util.Objects;
import static android.Manifest.permission.CAMERA; import static android.Manifest.permission.CAMERA;
import static android.Manifest.permission.RECORD_AUDIO; import static android.Manifest.permission.RECORD_AUDIO;
@ -218,6 +225,59 @@ public final class NativeLibrary {
} }
private static boolean coreErrorAlertResult = false; 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. * 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. // 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. // Wait for the lock to notify that it is complete.
synchronized (lock) { synchronized (coreErrorAlertLock) {
try { try {
lock.wait(); coreErrorAlertLock.wait();
} catch (Exception ignored) { } catch (Exception ignored) {
} }
} }