From 0c4d6d85a30e35d89d4e290e7c49c5a599e00323 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20K=C3=BCrten?= <sebastian@mobanisto.de>
Date: Fri, 12 Aug 2022 11:31:57 +0200
Subject: [PATCH] Cancel db check job to avoid duplicate navigation

---
 .../briarproject/mailbox/android/ui/MainActivity.kt | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

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 f126a9aa..2e0864f4 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
@@ -32,6 +32,8 @@ import androidx.lifecycle.lifecycleScope
 import androidx.navigation.NavController
 import androidx.navigation.fragment.NavHostFragment
 import dagger.hilt.android.AndroidEntryPoint
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.isActive
 import kotlinx.coroutines.launch
 import org.briarproject.android.dontkillmelib.DozeUtils.needsDozeWhitelisting
 import org.briarproject.mailbox.NavOnboardingDirections.actionGlobalClockSkewFragment
@@ -158,9 +160,15 @@ class MainActivity : AppCompatActivity(), ActivityResultCallback<ActivityResult>
         }
     }
 
+    // Remember last db check job so that we can cancel the current one and launch a new one in case
+    // of onCreate() and onNewIntent() creating two jobs in quick succession.
+    private var lastDbCheck: Job? = null
+
     private fun checkForDbAsync() {
-        lifecycleScope.launch {
+        lastDbCheck?.cancel()
+        lastDbCheck = lifecycleScope.launch {
             val hasDb = viewModel.hasDb()
+            if (!isActive) return@launch
             LOG.info(
                 "hasDb? $hasDb, hadBeenStartedOnSave? $hadBeenStartedOnSave, " +
                     "onboarding launched? $onboardingLaunched, onboarding done? $onboardingDone"
@@ -188,7 +196,8 @@ class MainActivity : AppCompatActivity(), ActivityResultCallback<ActivityResult>
         if (!hasDb && !onboardingDone) {
             // Make sure not to launch onboarding twice. In case of MainActivity being killed (due
             // to do-not-keep activities option enabled), onDbChecked() gets called twice when
-            // relaunched via app launcher (through onNewIntent()).
+            // relaunched via app launcher (through onNewIntent()). Even though we cancel the job
+            // there is a slight chance that both jobs finish.
             if (!onboardingLaunched.getAndSet(true)) {
                 LOG.info("launching onboarding activity")
                 startForResult.launch(Intent(this, OnboardingActivity::class.java))
-- 
GitLab