Merge pull request #8452 from JosJuice/android-emulationactivity-rotation-crash

Android: Replace emulation rotation crash workaround with proper fix
This commit is contained in:
Connor McLaughlin
2019-11-08 10:45:21 +10:00
committed by GitHub
6 changed files with 36 additions and 24 deletions

View File

@ -400,6 +400,8 @@ public final class NativeLibrary
*/
public static native void StopEmulation();
public static native void WaitUntilDoneBooting();
/**
* Returns true if emulation is running (or is paused).
*/

View File

@ -235,10 +235,6 @@ public final class EmulationActivity extends AppCompatActivity
{
super.onCreate(savedInstanceState);
// Find the EmulationFragment
mEmulationFragment = (EmulationFragment) getSupportFragmentManager()
.findFragmentById(R.id.frame_emulation_fragment);
if (savedInstanceState == null)
{
// Get params we were passed
@ -251,9 +247,7 @@ public final class EmulationActivity extends AppCompatActivity
}
else
{
// Could have recreated the activity(rotate) before creating the fragment. If the fragment
// doesn't exist, treat this as a new start.
activityRecreated = mEmulationFragment != null;
activityRecreated = true;
restoreState(savedInstanceState);
}
@ -311,9 +305,10 @@ public final class EmulationActivity extends AppCompatActivity
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}
if (!(mDeviceHasTouchScreen && lockLandscape &&
getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) &&
mEmulationFragment == null)
// Find or create the EmulationFragment
mEmulationFragment = (EmulationFragment) getSupportFragmentManager()
.findFragmentById(R.id.frame_emulation_fragment);
if (mEmulationFragment == null)
{
mEmulationFragment = EmulationFragment.newInstance(mPaths);
getSupportFragmentManager().beginTransaction()

View File

@ -316,8 +316,6 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
state = State.PAUSED;
Log.debug("[EmulationFragment] Pausing emulation.");
// Release the surface before pausing, since emulation has to be running for that.
NativeLibrary.SurfaceDestroyed();
NativeLibrary.PauseEmulation();
}
else
@ -381,19 +379,17 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
mSurface = null;
Log.debug("[EmulationFragment] Surface destroyed.");
if (state == State.RUNNING)
if (state != State.STOPPED)
{
NativeLibrary.SurfaceDestroyed();
state = State.PAUSED;
}
else if (state == State.PAUSED)
{
Log.warning("[EmulationFragment] Surface cleared while emulation paused.");
}
else
{
Log.warning("[EmulationFragment] Surface cleared while emulation stopped.");
// 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();
}
}