Compare commits

...

3 Commits

Author SHA1 Message Date
Greyson Parrelli
508688e533 Bump version to 7.11.4 2024-07-22 11:26:57 -04:00
Greyson Parrelli
eef0f299b7 Fix welcome screen button after pressing back on transfer screen. 2024-07-22 11:22:16 -04:00
Nicholas Tinsley
f9e8ace5f7 Run registration UI callbacks in LifeycleScope. 2024-07-22 11:21:51 -04:00
5 changed files with 83 additions and 98 deletions

View File

@@ -22,8 +22,8 @@ plugins {
apply(from = "static-ips.gradle.kts")
val canonicalVersionCode = 1436
val canonicalVersionName = "7.11.3"
val currentHotfixVersion = 0
val canonicalVersionName = "7.11.4"
val currentHotfixVersion = 1
val maxHotfixVersions = 100
val keystores: Map<String, Properties?> = mapOf("debug" to loadKeystoreProperties("keystore.debug.properties"))

View File

@@ -5,19 +5,9 @@
package org.thoughtcrime.securesms.registration.ui
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import com.google.i18n.phonenumbers.PhoneNumberUtil
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber
fun PhoneNumber.toE164(): String {
return PhoneNumberUtil.getInstance().format(this, PhoneNumberUtil.PhoneNumberFormat.E164)
}
fun Fragment.isBindingInvalid(): Boolean {
if (view == null) {
return false
}
return viewLifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)
}

View File

@@ -11,10 +11,12 @@ import android.view.View
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.fragment.findNavController
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.i18n.phonenumbers.PhoneNumberUtil
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.signal.core.util.logging.Log
@@ -31,7 +33,6 @@ import org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegat
import org.thoughtcrime.securesms.registration.fragments.SignalStrengthPhoneStateListener
import org.thoughtcrime.securesms.registration.ui.RegistrationCheckpoint
import org.thoughtcrime.securesms.registration.ui.RegistrationViewModel
import org.thoughtcrime.securesms.registration.ui.isBindingInvalid
import org.thoughtcrime.securesms.util.concurrent.AssertedSuccessListener
import org.thoughtcrime.securesms.util.navigation.safeNavigate
import org.thoughtcrime.securesms.util.visible
@@ -48,17 +49,15 @@ class EnterCodeFragment : LoggingFragment(R.layout.fragment_registration_enter_c
private val TAG = Log.tag(EnterCodeFragment::class.java)
private val sharedViewModel by activityViewModels<RegistrationViewModel>()
private val bottomSheet = ContactSupportBottomSheetFragment()
private val binding: FragmentRegistrationEnterCodeBinding by ViewBinderDelegate(FragmentRegistrationEnterCodeBinding::bind)
private lateinit var phoneStateListener: SignalStrengthPhoneStateListener
private var autopilotCodeEntryActive = false
private val bottomSheet = ContactSupportBottomSheetFragment()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setDebugLogSubmitMultiTapView(binding.verifyHeader)
phoneStateListener = SignalStrengthPhoneStateListener(this, PhoneStateCallback())
@@ -134,34 +133,28 @@ class EnterCodeFragment : LoggingFragment(R.layout.fragment_registration_enter_c
}
private fun handleSessionErrorResponse(result: RegistrationResult) {
if (isBindingInvalid()) {
Log.w(TAG, "Binding not valid, aborting! Result: $result")
result.logCause()
return
}
when (result) {
is VerificationCodeRequestResult.Success -> binding.keyboard.displaySuccess()
is VerificationCodeRequestResult.RateLimited -> presentRateLimitedDialog()
is VerificationCodeRequestResult.AttemptsExhausted -> presentAccountLocked()
is VerificationCodeRequestResult.RegistrationLocked -> presentRegistrationLocked(result.timeRemaining)
else -> presentGenericError(result)
viewLifecycleOwner.lifecycleScope.launch {
when (result) {
is VerificationCodeRequestResult.Success -> binding.keyboard.displaySuccess()
is VerificationCodeRequestResult.RateLimited -> presentRateLimitedDialog()
is VerificationCodeRequestResult.AttemptsExhausted -> presentAccountLocked()
is VerificationCodeRequestResult.RegistrationLocked -> presentRegistrationLocked(result.timeRemaining)
else -> presentGenericError(result)
}
}
}
private fun handleRegistrationErrorResponse(result: RegisterAccountResult) {
if (isBindingInvalid()) {
Log.w(TAG, "Binding not valid, aborting! Result: $result")
result.logCause()
return
}
when (result) {
is RegisterAccountResult.Success -> binding.keyboard.displaySuccess()
is RegisterAccountResult.RegistrationLocked -> presentRegistrationLocked(result.timeRemaining)
is RegisterAccountResult.AuthorizationFailed -> presentIncorrectCodeDialog()
is RegisterAccountResult.AttemptsExhausted -> presentAccountLocked()
is RegisterAccountResult.RateLimited -> presentRateLimitedDialog()
viewLifecycleOwner.lifecycleScope.launch {
when (result) {
is RegisterAccountResult.Success -> binding.keyboard.displaySuccess()
is RegisterAccountResult.RegistrationLocked -> presentRegistrationLocked(result.timeRemaining)
is RegisterAccountResult.AuthorizationFailed -> presentIncorrectCodeDialog()
is RegisterAccountResult.AttemptsExhausted -> presentAccountLocked()
is RegisterAccountResult.RateLimited -> presentRateLimitedDialog()
else -> presentGenericError(result)
else -> presentGenericError(result)
}
}
}
@@ -209,22 +202,19 @@ class EnterCodeFragment : LoggingFragment(R.layout.fragment_registration_enter_c
private fun presentIncorrectCodeDialog() {
sharedViewModel.incrementIncorrectCodeAttempts()
Toast.makeText(requireContext(), R.string.RegistrationActivity_incorrect_code, Toast.LENGTH_LONG).show()
viewLifecycleOwner.lifecycleScope.launch {
Toast.makeText(requireContext(), R.string.RegistrationActivity_incorrect_code, Toast.LENGTH_LONG).show()
if (isBindingInvalid()) {
Log.w(TAG, "Binding not valid, aborting updating keyboard!")
return
binding.keyboard.displayFailure().addListener(object : AssertedSuccessListener<Boolean?>() {
override fun onSuccess(result: Boolean?) {
binding.callMeCountDown.visibility = View.VISIBLE
binding.resendSmsCountDown.visibility = View.VISIBLE
binding.wrongNumber.visibility = View.VISIBLE
binding.code.clear()
binding.keyboard.displayKeyboard()
}
})
}
binding.keyboard.displayFailure().addListener(object : AssertedSuccessListener<Boolean?>() {
override fun onSuccess(result: Boolean?) {
binding.callMeCountDown.visibility = View.VISIBLE
binding.resendSmsCountDown.visibility = View.VISIBLE
binding.wrongNumber.visibility = View.VISIBLE
binding.code.clear()
binding.keyboard.displayKeyboard()
}
})
}
private fun presentGenericError(requestResult: RegistrationResult) {

View File

@@ -25,6 +25,7 @@ import androidx.core.view.MenuProvider
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.fragment.findNavController
import com.google.android.gms.common.ConnectionResult
@@ -35,6 +36,7 @@ import com.google.android.material.textfield.TextInputEditText
import com.google.i18n.phonenumbers.NumberParseException
import com.google.i18n.phonenumbers.PhoneNumberUtil
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber
import kotlinx.coroutines.launch
import org.signal.core.util.isNotNullOrBlank
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.LoggingFragment
@@ -51,7 +53,6 @@ import org.thoughtcrime.securesms.registration.fragments.RegistrationViewDelegat
import org.thoughtcrime.securesms.registration.ui.RegistrationCheckpoint
import org.thoughtcrime.securesms.registration.ui.RegistrationState
import org.thoughtcrime.securesms.registration.ui.RegistrationViewModel
import org.thoughtcrime.securesms.registration.ui.isBindingInvalid
import org.thoughtcrime.securesms.registration.ui.toE164
import org.thoughtcrime.securesms.registration.util.CountryPrefix
import org.thoughtcrime.securesms.util.CommunicationActions
@@ -300,54 +301,59 @@ class EnterPhoneNumberFragment : LoggingFragment(R.layout.fragment_registration_
}
private fun handleErrorResponse(result: RegistrationResult) {
if (isBindingInvalid()) {
Log.w(TAG, "Binding not valid, aborting! Result: $result")
result.logCause()
return
}
if (!result.isSuccess()) {
Log.i(TAG, "Handling error response.", result.getCause())
}
when (result) {
is RegistrationSessionCreationResult.Success,
is VerificationCodeRequestResult.Success -> Unit
is RegistrationSessionCreationResult.AttemptsExhausted,
is VerificationCodeRequestResult.AttemptsExhausted -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_rate_limited_to_service))
is VerificationCodeRequestResult.ChallengeRequired -> {
handleChallenges(result.challenges)
viewLifecycleOwner.lifecycleScope.launch {
if (!result.isSuccess()) {
Log.i(TAG, "Handling error response.", result.getCause())
}
is VerificationCodeRequestResult.ExternalServiceFailure -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_unable_to_connect_to_service), skipToNextScreen)
is VerificationCodeRequestResult.ImpossibleNumber -> {
MaterialAlertDialogBuilder(requireContext()).apply {
setMessage(getString(R.string.RegistrationActivity_the_number_you_specified_s_is_invalid, fragmentViewModel.phoneNumber?.toE164()))
setPositiveButton(android.R.string.ok, null)
show()
when (result) {
is RegistrationSessionCreationResult.Success,
is VerificationCodeRequestResult.Success -> Unit
is RegistrationSessionCreationResult.AttemptsExhausted,
is VerificationCodeRequestResult.AttemptsExhausted -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_rate_limited_to_service))
is VerificationCodeRequestResult.ChallengeRequired -> {
handleChallenges(result.challenges)
}
}
is VerificationCodeRequestResult.InvalidTransportModeFailure -> {
MaterialAlertDialogBuilder(requireContext()).apply {
setMessage(R.string.RegistrationActivity_we_couldnt_send_you_a_verification_code)
setPositiveButton(R.string.RegistrationActivity_voice_call) { _, _ ->
sharedViewModel.requestVerificationCall(requireContext(), ::handleErrorResponse)
is VerificationCodeRequestResult.ExternalServiceFailure -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_unable_to_connect_to_service), skipToNextScreen)
is VerificationCodeRequestResult.ImpossibleNumber -> {
MaterialAlertDialogBuilder(requireContext()).apply {
setMessage(getString(R.string.RegistrationActivity_the_number_you_specified_s_is_invalid, fragmentViewModel.phoneNumber?.toE164()))
setPositiveButton(android.R.string.ok, null)
show()
}
setNegativeButton(R.string.RegistrationActivity_cancel, null)
show()
}
is VerificationCodeRequestResult.InvalidTransportModeFailure -> {
MaterialAlertDialogBuilder(requireContext()).apply {
setMessage(R.string.RegistrationActivity_we_couldnt_send_you_a_verification_code)
setPositiveButton(R.string.RegistrationActivity_voice_call) { _, _ ->
sharedViewModel.requestVerificationCall(requireContext(), ::handleErrorResponse)
}
setNegativeButton(R.string.RegistrationActivity_cancel, null)
show()
}
}
is RegistrationSessionCreationResult.MalformedRequest,
is VerificationCodeRequestResult.MalformedRequest -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_unable_to_connect_to_service), skipToNextScreen)
is VerificationCodeRequestResult.MustRetry -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_unable_to_connect_to_service), skipToNextScreen)
is VerificationCodeRequestResult.NonNormalizedNumber -> handleNonNormalizedNumberError(result.originalNumber, result.normalizedNumber, fragmentViewModel.mode)
is RegistrationSessionCreationResult.RateLimited -> {
Log.i(TAG, "Session creation rate limited! Next attempt: ${result.timeRemaining.milliseconds}")
presentRemoteErrorDialog(getString(R.string.RegistrationActivity_rate_limited_to_try_again, result.timeRemaining.milliseconds.toString()))
}
is VerificationCodeRequestResult.RateLimited -> {
Log.i(TAG, "Code request rate limited! Next attempt: ${result.timeRemaining.milliseconds}")
presentRemoteErrorDialog(getString(R.string.RegistrationActivity_rate_limited_to_try_again, result.timeRemaining.milliseconds.toString()))
}
is VerificationCodeRequestResult.TokenNotAccepted -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_we_need_to_verify_that_youre_human)) { _, _ -> moveToCaptcha() }
else -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_unable_to_connect_to_service))
}
is RegistrationSessionCreationResult.MalformedRequest,
is VerificationCodeRequestResult.MalformedRequest -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_unable_to_connect_to_service), skipToNextScreen)
is VerificationCodeRequestResult.MustRetry -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_unable_to_connect_to_service), skipToNextScreen)
is VerificationCodeRequestResult.NonNormalizedNumber -> handleNonNormalizedNumberError(result.originalNumber, result.normalizedNumber, fragmentViewModel.mode)
is RegistrationSessionCreationResult.RateLimited -> {
Log.i(TAG, "Session creation rate limited! Next attempt: ${result.timeRemaining.milliseconds}")
presentRemoteErrorDialog(getString(R.string.RegistrationActivity_rate_limited_to_try_again, result.timeRemaining.milliseconds.toString()))
}
is VerificationCodeRequestResult.RateLimited -> {
Log.i(TAG, "Code request rate limited! Next attempt: ${result.timeRemaining.milliseconds}")
presentRemoteErrorDialog(getString(R.string.RegistrationActivity_rate_limited_to_try_again, result.timeRemaining.milliseconds.toString()))
}
is VerificationCodeRequestResult.TokenNotAccepted -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_we_need_to_verify_that_youre_human)) { _, _ -> moveToCaptcha() }
else -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_unable_to_connect_to_service))
}
}

View File

@@ -48,7 +48,6 @@ class WelcomeFragment : LoggingFragment(R.layout.fragment_registration_welcome)
}
Activity.RESULT_CANCELED -> {
Log.w(TAG, "Backup restoration canceled.")
findNavController().popBackStack()
}
else -> Log.w(TAG, "Backup restoration activity ended with unknown result code: $resultCode")
}