Fix bad state when in restore flow and become unregistered.

This commit is contained in:
Cody Henthorne
2025-10-08 14:04:41 -04:00
committed by Alex Hart
parent a5cca5b0fd
commit 0f35eb7f7b
4 changed files with 71 additions and 0 deletions

View File

@@ -48,11 +48,14 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
@@ -62,6 +65,8 @@ import org.signal.core.ui.compose.DayNightPreviews
import org.signal.core.ui.compose.Dialogs
import org.signal.core.ui.compose.Previews
import org.signal.core.ui.compose.theme.SignalTheme
import org.signal.core.util.AppUtil
import org.signal.core.util.ThreadUtil
import org.signal.core.util.bytes
import org.thoughtcrime.securesms.BaseActivity
import org.thoughtcrime.securesms.MainActivity
@@ -81,6 +86,7 @@ import org.thoughtcrime.securesms.registration.ui.shared.RegistrationScreenTitle
import org.thoughtcrime.securesms.registration.util.RegistrationUtil
import org.thoughtcrime.securesms.util.DateUtils
import org.thoughtcrime.securesms.util.PlayStoreUtil
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.thoughtcrime.securesms.util.viewModel
import java.util.Locale
import kotlin.time.Duration
@@ -150,6 +156,18 @@ class RemoteRestoreActivity : BaseActivity() {
}
}
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
while (isActive) {
if (TextSecurePreferences.isUnauthorizedReceived(this@RemoteRestoreActivity)) {
ThreadUtil.runOnMain { showUnregisteredDialog() }
break
}
delay(1000)
}
}
}
setContent {
val state: RemoteRestoreViewModel.ScreenState by viewModel.state.collectAsStateWithLifecycle()
val contactSupportState: ContactSupportViewModel.ContactSupportState<ContactSupportReason> by contactSupportViewModel.state.collectAsStateWithLifecycle()
@@ -225,6 +243,15 @@ class RemoteRestoreActivity : BaseActivity() {
viewModel.updateRestoreProgress(restoreEvent)
}
private fun showUnregisteredDialog() {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.RestoreActivity__no_longer_registered_title)
.setMessage(R.string.RestoreActivity__no_longer_registered_message)
.setCancelable(false)
.setPositiveButton(android.R.string.ok) { _, _ -> AppUtil.clearData(this) }
.show()
}
enum class ContactSupportReason {
NetworkError, SvrBFailure
}

View File

@@ -10,9 +10,18 @@ import android.content.Intent
import android.os.Bundle
import androidx.activity.OnBackPressedCallback
import androidx.activity.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.navigation.fragment.NavHostFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import org.signal.core.util.AppUtil
import org.signal.core.util.ThreadUtil
import org.signal.core.util.getParcelableExtraCompat
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.BaseActivity
@@ -21,6 +30,7 @@ import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.RestoreDirections
import org.thoughtcrime.securesms.registration.ui.restore.RemoteRestoreActivity
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.thoughtcrime.securesms.util.navigation.safeNavigate
/**
@@ -80,6 +90,18 @@ class RestoreActivity : BaseActivity() {
}
}
)
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
while (isActive) {
if (TextSecurePreferences.isUnauthorizedReceived(this@RestoreActivity)) {
ThreadUtil.runOnMain { showUnregisteredDialog() }
break
}
delay(1000)
}
}
}
}
override fun onResume() {
@@ -106,6 +128,15 @@ class RestoreActivity : BaseActivity() {
finish()
}
private fun showUnregisteredDialog() {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.RestoreActivity__no_longer_registered_title)
.setMessage(R.string.RestoreActivity__no_longer_registered_message)
.setCancelable(false)
.setPositiveButton(android.R.string.ok) { _, _ -> AppUtil.clearData(this) }
.show()
}
companion object {
private val TAG = Log.tag(RestoreActivity::class)

View File

@@ -1494,6 +1494,10 @@
<string name="RemoteRestoreActivity__not_now">Not now</string>
<!-- Text shown on restore screen as information on what will happen if you skip -->
<string name="RemoteRestoreActivity__your_media_will_restore_in_the_background">Your media will restore in the background. If you choose not to restore now, you won\'t be able to restore later.</string>
<!-- Dialog title -->
<string name="RestoreActivity__no_longer_registered_title">This device is no longer registered</string>
<!-- Dialog message -->
<string name="RestoreActivity__no_longer_registered_message">This is likely because you registered your Signal account on a different device.</string>
<!-- GroupMentionSettingDialog -->
<string name="GroupMentionSettingDialog_notify_me_for_mentions">Notify me for Mentions</string>

View File

@@ -1,9 +1,11 @@
package org.signal.core.util;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
public final class AppUtil {
@@ -21,4 +23,11 @@ public final class AppUtil {
context.startActivity(defaultIntent);
Runtime.getRuntime().exit(0);
}
/**
* Clears all app data, will cause the app to stop running.
*/
public static void clearData(@NonNull Context context) {
ContextCompat.getSystemService(context, ActivityManager.class).clearApplicationUserData();
}
}