diff options
| author | JosJuice <josjuice@gmail.com> | 2020-11-09 10:46:08 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-09 10:46:08 +0100 |
| commit | 72997c17d02b60386c564124f63d33cdf3743475 (patch) | |
| tree | c754b7716ecfa42a475fc74cb10c3f2dffcba240 /Source/Android/app/src/main/java | |
| parent | a9ef7e0e436795d1ef842aae7433c6173f623f90 (diff) | |
| parent | 8181a7b3dd932a3035b9fc56f6def70c0cc05c59 (diff) | |
Merge pull request #9229 from JosJuice/android-emulationactivity-finish
Android: Handle failed boots correctly
Diffstat (limited to 'Source/Android/app/src/main/java')
4 files changed, 52 insertions, 27 deletions
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 199d80cf72..486e5bab7d 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 @@ -12,6 +12,8 @@ import android.util.DisplayMetrics; import android.view.Surface; import android.widget.Toast; +import androidx.fragment.app.FragmentManager; + import org.dolphinemu.dolphinemu.activities.EmulationActivity; import org.dolphinemu.dolphinemu.dialogs.AlertMessage; import org.dolphinemu.dolphinemu.utils.CompressCallback; @@ -403,15 +405,13 @@ public final class NativeLibrary */ public static native void StopEmulation(); - public static native boolean IsBooting(); - - public static native void WaitUntilDoneBooting(); - /** * Returns true if emulation is running (or is paused). */ public static native boolean IsRunning(); + public static native boolean IsRunningAndStarted(); + /** * Enables or disables CPU block profiling * @@ -487,7 +487,7 @@ public final class NativeLibrary private static native String GetCurrentTitleDescriptionUnchecked(); public static boolean displayAlertMsg(final String caption, final String text, - final boolean yesNo, final boolean isWarning) + final boolean yesNo, final boolean isWarning, final boolean nonBlocking) { Log.error("[NativeLibrary] Alert: " + text); final EmulationActivity emulationActivity = sEmulationActivity.get(); @@ -498,10 +498,9 @@ public final class NativeLibrary } else { - // AlertMessages while the core is booting will deadlock if WaitUntilDoneBooting is called. - // We also can't use AlertMessages unless we have a non-null activity reference. - // As a fallback, we use toasts instead. - if (emulationActivity == null || IsBooting()) + // We can't use AlertMessages unless we have a non-null activity reference + // and are allowed to block. As a fallback, we can use toasts. + if (emulationActivity == null || nonBlocking) { new Handler(Looper.getMainLooper()).post( () -> Toast.makeText(DolphinApplication.getAppContext(), text, Toast.LENGTH_LONG) @@ -511,9 +510,22 @@ public final class NativeLibrary { sIsShowingAlertMessage = true; - emulationActivity.runOnUiThread( - () -> AlertMessage.newInstance(caption, text, yesNo, isWarning) - .show(emulationActivity.getSupportFragmentManager(), "AlertMessage")); + emulationActivity.runOnUiThread(() -> + { + FragmentManager fragmentManager = emulationActivity.getSupportFragmentManager(); + if (fragmentManager.isStateSaved()) + { + // The activity is being destroyed, so we can't use it to display an AlertMessage. + // Fall back to a toast. + Toast.makeText(emulationActivity, text, Toast.LENGTH_LONG).show(); + NotifyAlertMessageLock(); + } + else + { + AlertMessage.newInstance(caption, text, yesNo, isWarning) + .show(fragmentManager, "AlertMessage"); + } + }); // Wait for the lock to notify that it is complete. synchronized (sAlertMessageLock) @@ -563,6 +575,20 @@ public final class NativeLibrary sEmulationActivity.clear(); } + public static void finishEmulationActivity() + { + final EmulationActivity emulationActivity = sEmulationActivity.get(); + if (emulationActivity == null) + { + Log.warning("[NativeLibrary] EmulationActivity is null."); + } + else + { + Log.verbose("[NativeLibrary] Finishing EmulationActivity."); + emulationActivity.runOnUiThread(emulationActivity::finish); + } + } + public static void updateTouchPointer() { final EmulationActivity emulationActivity = sEmulationActivity.get(); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index 49f9704e86..08a36aecbf 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -81,10 +81,12 @@ public final class EmulationActivity extends AppCompatActivity private String[] mPaths; private boolean mIgnoreWarnings; private static boolean sUserPausedEmulation; + private boolean mMenuToastShown; public static final String EXTRA_SELECTED_GAMES = "SelectedGames"; public static final String EXTRA_IGNORE_WARNINGS = "IgnoreWarnings"; public static final String EXTRA_USER_PAUSED_EMULATION = "sUserPausedEmulation"; + public static final String EXTRA_MENU_TOAST_SHOWN = "MenuToastShown"; @Retention(SOURCE) @IntDef({MENU_ACTION_EDIT_CONTROLS_PLACEMENT, MENU_ACTION_TOGGLE_CONTROLS, MENU_ACTION_ADJUST_SCALE, @@ -212,8 +214,8 @@ public final class EmulationActivity extends AppCompatActivity mPaths = gameToEmulate.getStringArrayExtra(EXTRA_SELECTED_GAMES); mIgnoreWarnings = gameToEmulate.getBooleanExtra(EXTRA_IGNORE_WARNINGS, false); sUserPausedEmulation = gameToEmulate.getBooleanExtra(EXTRA_USER_PAUSED_EMULATION, false); + mMenuToastShown = false; activityRecreated = false; - Toast.makeText(this, R.string.emulation_menu_help, Toast.LENGTH_LONG).show(); } else { @@ -260,8 +262,9 @@ public final class EmulationActivity extends AppCompatActivity mEmulationFragment.saveTemporaryState(); } outState.putStringArray(EXTRA_SELECTED_GAMES, mPaths); - outState.putBoolean(EXTRA_USER_PAUSED_EMULATION, mIgnoreWarnings); + outState.putBoolean(EXTRA_IGNORE_WARNINGS, mIgnoreWarnings); outState.putBoolean(EXTRA_USER_PAUSED_EMULATION, sUserPausedEmulation); + outState.putBoolean(EXTRA_MENU_TOAST_SHOWN, mMenuToastShown); super.onSaveInstanceState(outState); } @@ -270,6 +273,7 @@ public final class EmulationActivity extends AppCompatActivity mPaths = savedInstanceState.getStringArray(EXTRA_SELECTED_GAMES); mIgnoreWarnings = savedInstanceState.getBoolean(EXTRA_IGNORE_WARNINGS); sUserPausedEmulation = savedInstanceState.getBoolean(EXTRA_USER_PAUSED_EMULATION); + mMenuToastShown = savedInstanceState.getBoolean(EXTRA_MENU_TOAST_SHOWN); } @Override @@ -306,6 +310,13 @@ public final class EmulationActivity extends AppCompatActivity public void onTitleChanged() { + if (!mMenuToastShown) + { + // The reason why this doesn't run earlier is because we want to be sure the boot succeeded. + Toast.makeText(this, R.string.emulation_menu_help, Toast.LENGTH_LONG).show(); + mMenuToastShown = true; + } + setTitle(NativeLibrary.GetCurrentTitleDescription()); updateMotionListener(); @@ -342,7 +353,6 @@ public final class EmulationActivity extends AppCompatActivity if (keyCode == KeyEvent.KEYCODE_BACK) { mEmulationFragment.stopEmulation(); - finish(); return true; } return super.onKeyLongPress(keyCode, event); @@ -617,7 +627,6 @@ public final class EmulationActivity extends AppCompatActivity case MENU_ACTION_EXIT: mEmulationFragment.stopEmulation(); - finish(); break; } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java index 4cdb0051e5..cfcd28ea02 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java @@ -330,16 +330,6 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C mSurface = null; Log.debug("[EmulationFragment] Surface destroyed."); - if (state != State.STOPPED && !NativeLibrary.IsShowingAlertMessage()) - { - // In order to avoid dereferencing nullptr, we must not destroy the surface while booting - // the core, so wait here if necessary. An easy (but not 100% consistent) way to reach - // this method while the core is booting is by having landscape orientation lock enabled - // and starting emulation while the phone is in portrait mode, leading to the activity - // being recreated very soon after NativeLibrary.Run has been called. - NativeLibrary.WaitUntilDoneBooting(); - } - NativeLibrary.SurfaceDestroyed(); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java index fe37981ab5..e9abd1a05b 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java @@ -148,7 +148,7 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener public void initTouchPointer() { // Check if we have all the data we need yet - boolean aspectRatioAvailable = NativeLibrary.IsRunning() && !NativeLibrary.IsBooting(); + boolean aspectRatioAvailable = NativeLibrary.IsRunningAndStarted(); if (!aspectRatioAvailable || mSurfacePosition == null) return; |
