diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.kt index e4698ba43c..e0efc43611 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.kt @@ -119,7 +119,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { } override fun onDetach() { - NativeLibrary.clearEmulationActivity() + // Don't clear the reference if a newer EmulationActivity already took over + if (NativeLibrary.getEmulationActivity() === emulationActivity) { + NativeLibrary.clearEmulationActivity() + } super.onDetach() } @@ -154,7 +157,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { override fun surfaceDestroyed(holder: SurfaceHolder) { Log.debug("[EmulationFragment] Surface destroyed.") - NativeLibrary.SurfaceDestroyed() + // Don't tear down the surface if a newer EmulationActivity already took over + if (NativeLibrary.getEmulationActivity() === emulationActivity) { + NativeLibrary.SurfaceDestroyed() + } runWhenSurfaceIsValid = true } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.kt index 761c6dbfef..d61f1097c8 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.kt @@ -2,6 +2,7 @@ package org.dolphinemu.dolphinemu.ui.main +import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.view.Menu @@ -90,6 +91,12 @@ class MainActivity : AppCompatActivity(), MainView, OnRefreshListener, ThemeProv } } + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + StartupHandler.HandleInit(this) + } + override fun onResume() { ThemeHelper.setCorrectTheme(this) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.kt index 09bacd201b..2cd8288eb4 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.kt @@ -66,6 +66,12 @@ class TvMainActivity : FragmentActivity(), MainView, OnRefreshListener { } } + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + StartupHandler.HandleInit(this) + } + override fun onResume() { super.onResume() if (DirectoryInitialization.shouldStart(this)) { diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java index db003b82b2..775e8a3330 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/StartupHandler.java @@ -9,7 +9,10 @@ import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.text.TextUtils; +import android.util.Log; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.LifecycleOwner; @@ -38,11 +41,44 @@ public final class StartupHandler String[] gamesToLaunch = getGamesFromIntent(parent.getIntent()); if (gamesToLaunch != null && gamesToLaunch.length > 0) { - // Start the emulation activity, send the ISO passed in and finish the main activity - EmulationActivity.launch(parent, gamesToLaunch, false, true); + // If a previous session is still running, stop it and wait for it to finish + // before launching the new game. StopEmulation is async, so launching immediately + // would race with the old emulation thread's cleanup. + if (!NativeLibrary.IsUninitialized()) + { + NativeLibrary.StopEmulation(); + waitForStopThenLaunch(parent, gamesToLaunch); + } + else + { + EmulationActivity.stopIgnoringLaunchRequests(); + EmulationActivity.launch(parent, gamesToLaunch, false, true); + } } } + private static void waitForStopThenLaunch(FragmentActivity parent, String[] gamesToLaunch) + { + Handler handler = new Handler(Looper.getMainLooper()); + final long deadline = System.currentTimeMillis() + 5000; + handler.postDelayed(new Runnable() + { + @Override + public void run() + { + if (NativeLibrary.IsUninitialized() || System.currentTimeMillis() >= deadline) + { + EmulationActivity.stopIgnoringLaunchRequests(); + EmulationActivity.launch(parent, gamesToLaunch, false, true); + } + else + { + handler.postDelayed(this, 100); + } + } + }, 100); + } + private static String[] getGamesFromIntent(Intent intent) { // Priority order when looking for game paths in an intent: