diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt index 5b53b17e82..4f4e5fe913 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/ui/restore/RemoteRestoreActivity.kt @@ -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 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 } diff --git a/app/src/main/java/org/thoughtcrime/securesms/restore/RestoreActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/restore/RestoreActivity.kt index fd2ab95c8b..dfca4dcdf9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/restore/RestoreActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/restore/RestoreActivity.kt @@ -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) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bd33ac1fad..fd08a08182 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1494,6 +1494,10 @@ Not now Your media will restore in the background. If you choose not to restore now, you won\'t be able to restore later. + + This device is no longer registered + + This is likely because you registered your Signal account on a different device. Notify me for Mentions diff --git a/core-util/src/main/java/org/signal/core/util/AppUtil.java b/core-util/src/main/java/org/signal/core/util/AppUtil.java index 6a3cd667be..3b4afe487e 100644 --- a/core-util/src/main/java/org/signal/core/util/AppUtil.java +++ b/core-util/src/main/java/org/signal/core/util/AppUtil.java @@ -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(); + } }