diff --git a/mailbox-android/src/main/java/org/briarproject/mailbox/android/ui/MainActivity.kt b/mailbox-android/src/main/java/org/briarproject/mailbox/android/ui/MainActivity.kt index f78b1b3ef50993e4c8ca296f5d0646fce5f059c2..6f291f8fde471ed58502b0342fd573a271e341b6 100644 --- a/mailbox-android/src/main/java/org/briarproject/mailbox/android/ui/MainActivity.kt +++ b/mailbox-android/src/main/java/org/briarproject/mailbox/android/ui/MainActivity.kt @@ -36,6 +36,7 @@ import kotlinx.coroutines.launch import org.briarproject.android.dontkillmelib.DozeUtils.needsDozeWhitelisting import org.briarproject.mailbox.NavOnboardingDirections.actionGlobalClockSkewFragment import org.briarproject.mailbox.NavOnboardingDirections.actionGlobalDoNotKillMeFragment +import org.briarproject.mailbox.NavOnboardingDirections.actionGlobalInitFragment import org.briarproject.mailbox.NavOnboardingDirections.actionGlobalNoNetworkFragment import org.briarproject.mailbox.NavOnboardingDirections.actionGlobalQrCodeFragment import org.briarproject.mailbox.NavOnboardingDirections.actionGlobalStartupFragment @@ -80,6 +81,16 @@ class MainActivity : AppCompatActivity(), ActivityResultCallback<ActivityResult> LOG.info("onCreate()") setContentView(R.layout.activity_main) + // Check if the app has been restored with a UI from an old lifecycle while the app has been + // restarted with a new process and lifecycle. In that case, go back to the init fragment. + if (savedInstanceState != null) { + val hadBeenStartedOnSave = + savedInstanceState.getBoolean(BUNDLE_LIFECYCLE_BEYOND_NOT_STARTED) + if (viewModel.lifecycleState.value == NOT_STARTED && hadBeenStartedOnSave) { + nav.navigate(actionGlobalInitFragment()) + } + } + viewModel.doNotKillComplete.observe(this) { complete -> if (complete && nav.currentDestination?.id == R.id.doNotKillMeFragment) nav.navigate( actionGlobalStartupFragment() @@ -124,15 +135,7 @@ class MainActivity : AppCompatActivity(), ActivityResultCallback<ActivityResult> if (lifecycle.currentState == DESTROYED) { return } - if (savedInstanceState == null) { - if (!hasDb) { - startForResult.launch(Intent(this, OnboardingActivity::class.java)) - } else if (needsDozeWhitelisting(this)) { - nav.navigate(actionGlobalDoNotKillMeFragment()) - } else { - nav.navigate(actionGlobalStartupFragment()) - } - } else { + if (savedInstanceState != null) { // At this point, when we do not have a db, this can be either of two situations: // 1. We just came back from the onboarding activity and our MainActivity has been // destroyed in the meantime (can be forced using the do-not-keep-activities developer @@ -146,8 +149,22 @@ class MainActivity : AppCompatActivity(), ActivityResultCallback<ActivityResult> if (!hasDb && savedBeyondNotStarted) { finish() startActivity(Intent(this, WipeCompleteActivity::class.java)) + return } } + + // It is important to navigate here with and without a saved instance state. The normal + // case is that we do not have a saved instance state (when the app has just been started). + // However, when the service got killed and the app has been restored with a different UI + // state such as the qr code screen or the status screen, then we will have gone back to + // the init fragment during onCreate() and hence need to move forward here, too. + if (!hasDb) { + startForResult.launch(Intent(this, OnboardingActivity::class.java)) + } else if (needsDozeWhitelisting(this)) { + nav.navigate(actionGlobalDoNotKillMeFragment()) + } else { + nav.navigate(actionGlobalStartupFragment()) + } } override fun onSaveInstanceState(outState: Bundle) { diff --git a/mailbox-android/src/main/res/navigation/nav_main.xml b/mailbox-android/src/main/res/navigation/nav_main.xml index 1e8162752618a57754ec8fef1e1bf2458b6921cc..6c20c00a4554ea02dfce10f4fd786c75258d7f95 100644 --- a/mailbox-android/src/main/res/navigation/nav_main.xml +++ b/mailbox-android/src/main/res/navigation/nav_main.xml @@ -55,6 +55,11 @@ android:name="org.briarproject.mailbox.android.ui.WipingFragment" android:label="WipingFragment" tools:layout="@layout/fragment_wiping" /> + <action + android:id="@+id/action_global_initFragment" + app:destination="@id/initFragment" + app:popUpTo="@id/nav_onboarding" + app:popUpToInclusive="true" /> <action android:id="@+id/action_global_doNotKillMeFragment" app:destination="@id/doNotKillMeFragment"