mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-17 15:33:30 +01:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
508688e533 | ||
|
|
eef0f299b7 | ||
|
|
f9e8ace5f7 |
@@ -22,8 +22,8 @@ plugins {
|
|||||||
apply(from = "static-ips.gradle.kts")
|
apply(from = "static-ips.gradle.kts")
|
||||||
|
|
||||||
val canonicalVersionCode = 1436
|
val canonicalVersionCode = 1436
|
||||||
val canonicalVersionName = "7.11.3"
|
val canonicalVersionName = "7.11.4"
|
||||||
val currentHotfixVersion = 0
|
val currentHotfixVersion = 1
|
||||||
val maxHotfixVersions = 100
|
val maxHotfixVersions = 100
|
||||||
|
|
||||||
val keystores: Map<String, Properties?> = mapOf("debug" to loadKeystoreProperties("keystore.debug.properties"))
|
val keystores: Map<String, Properties?> = mapOf("debug" to loadKeystoreProperties("keystore.debug.properties"))
|
||||||
|
|||||||
@@ -5,19 +5,9 @@
|
|||||||
|
|
||||||
package org.thoughtcrime.securesms.registration.ui
|
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.PhoneNumberUtil
|
||||||
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber
|
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber
|
||||||
|
|
||||||
fun PhoneNumber.toE164(): String {
|
fun PhoneNumber.toE164(): String {
|
||||||
return PhoneNumberUtil.getInstance().format(this, PhoneNumberUtil.PhoneNumberFormat.E164)
|
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)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ import android.view.View
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import org.signal.core.util.logging.Log
|
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.fragments.SignalStrengthPhoneStateListener
|
||||||
import org.thoughtcrime.securesms.registration.ui.RegistrationCheckpoint
|
import org.thoughtcrime.securesms.registration.ui.RegistrationCheckpoint
|
||||||
import org.thoughtcrime.securesms.registration.ui.RegistrationViewModel
|
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.concurrent.AssertedSuccessListener
|
||||||
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
||||||
import org.thoughtcrime.securesms.util.visible
|
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 TAG = Log.tag(EnterCodeFragment::class.java)
|
||||||
|
|
||||||
private val sharedViewModel by activityViewModels<RegistrationViewModel>()
|
private val sharedViewModel by activityViewModels<RegistrationViewModel>()
|
||||||
|
private val bottomSheet = ContactSupportBottomSheetFragment()
|
||||||
private val binding: FragmentRegistrationEnterCodeBinding by ViewBinderDelegate(FragmentRegistrationEnterCodeBinding::bind)
|
private val binding: FragmentRegistrationEnterCodeBinding by ViewBinderDelegate(FragmentRegistrationEnterCodeBinding::bind)
|
||||||
|
|
||||||
private lateinit var phoneStateListener: SignalStrengthPhoneStateListener
|
private lateinit var phoneStateListener: SignalStrengthPhoneStateListener
|
||||||
|
|
||||||
private var autopilotCodeEntryActive = false
|
private var autopilotCodeEntryActive = false
|
||||||
|
|
||||||
private val bottomSheet = ContactSupportBottomSheetFragment()
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
setDebugLogSubmitMultiTapView(binding.verifyHeader)
|
setDebugLogSubmitMultiTapView(binding.verifyHeader)
|
||||||
|
|
||||||
phoneStateListener = SignalStrengthPhoneStateListener(this, PhoneStateCallback())
|
phoneStateListener = SignalStrengthPhoneStateListener(this, PhoneStateCallback())
|
||||||
@@ -134,34 +133,28 @@ class EnterCodeFragment : LoggingFragment(R.layout.fragment_registration_enter_c
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSessionErrorResponse(result: RegistrationResult) {
|
private fun handleSessionErrorResponse(result: RegistrationResult) {
|
||||||
if (isBindingInvalid()) {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
Log.w(TAG, "Binding not valid, aborting! Result: $result")
|
when (result) {
|
||||||
result.logCause()
|
is VerificationCodeRequestResult.Success -> binding.keyboard.displaySuccess()
|
||||||
return
|
is VerificationCodeRequestResult.RateLimited -> presentRateLimitedDialog()
|
||||||
}
|
is VerificationCodeRequestResult.AttemptsExhausted -> presentAccountLocked()
|
||||||
when (result) {
|
is VerificationCodeRequestResult.RegistrationLocked -> presentRegistrationLocked(result.timeRemaining)
|
||||||
is VerificationCodeRequestResult.Success -> binding.keyboard.displaySuccess()
|
else -> presentGenericError(result)
|
||||||
is VerificationCodeRequestResult.RateLimited -> presentRateLimitedDialog()
|
}
|
||||||
is VerificationCodeRequestResult.AttemptsExhausted -> presentAccountLocked()
|
|
||||||
is VerificationCodeRequestResult.RegistrationLocked -> presentRegistrationLocked(result.timeRemaining)
|
|
||||||
else -> presentGenericError(result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleRegistrationErrorResponse(result: RegisterAccountResult) {
|
private fun handleRegistrationErrorResponse(result: RegisterAccountResult) {
|
||||||
if (isBindingInvalid()) {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
Log.w(TAG, "Binding not valid, aborting! Result: $result")
|
when (result) {
|
||||||
result.logCause()
|
is RegisterAccountResult.Success -> binding.keyboard.displaySuccess()
|
||||||
return
|
is RegisterAccountResult.RegistrationLocked -> presentRegistrationLocked(result.timeRemaining)
|
||||||
}
|
is RegisterAccountResult.AuthorizationFailed -> presentIncorrectCodeDialog()
|
||||||
when (result) {
|
is RegisterAccountResult.AttemptsExhausted -> presentAccountLocked()
|
||||||
is RegisterAccountResult.Success -> binding.keyboard.displaySuccess()
|
is RegisterAccountResult.RateLimited -> presentRateLimitedDialog()
|
||||||
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() {
|
private fun presentIncorrectCodeDialog() {
|
||||||
sharedViewModel.incrementIncorrectCodeAttempts()
|
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()) {
|
binding.keyboard.displayFailure().addListener(object : AssertedSuccessListener<Boolean?>() {
|
||||||
Log.w(TAG, "Binding not valid, aborting updating keyboard!")
|
override fun onSuccess(result: Boolean?) {
|
||||||
return
|
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) {
|
private fun presentGenericError(requestResult: RegistrationResult) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import androidx.core.view.MenuProvider
|
|||||||
import androidx.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.google.android.gms.common.ConnectionResult
|
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.NumberParseException
|
||||||
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
import com.google.i18n.phonenumbers.PhoneNumberUtil
|
||||||
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber
|
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.signal.core.util.isNotNullOrBlank
|
import org.signal.core.util.isNotNullOrBlank
|
||||||
import org.signal.core.util.logging.Log
|
import org.signal.core.util.logging.Log
|
||||||
import org.thoughtcrime.securesms.LoggingFragment
|
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.RegistrationCheckpoint
|
||||||
import org.thoughtcrime.securesms.registration.ui.RegistrationState
|
import org.thoughtcrime.securesms.registration.ui.RegistrationState
|
||||||
import org.thoughtcrime.securesms.registration.ui.RegistrationViewModel
|
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.ui.toE164
|
||||||
import org.thoughtcrime.securesms.registration.util.CountryPrefix
|
import org.thoughtcrime.securesms.registration.util.CountryPrefix
|
||||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||||
@@ -300,54 +301,59 @@ class EnterPhoneNumberFragment : LoggingFragment(R.layout.fragment_registration_
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleErrorResponse(result: RegistrationResult) {
|
private fun handleErrorResponse(result: RegistrationResult) {
|
||||||
if (isBindingInvalid()) {
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
Log.w(TAG, "Binding not valid, aborting! Result: $result")
|
if (!result.isSuccess()) {
|
||||||
result.logCause()
|
Log.i(TAG, "Handling error response.", result.getCause())
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
is VerificationCodeRequestResult.ExternalServiceFailure -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_unable_to_connect_to_service), skipToNextScreen)
|
when (result) {
|
||||||
is VerificationCodeRequestResult.ImpossibleNumber -> {
|
is RegistrationSessionCreationResult.Success,
|
||||||
MaterialAlertDialogBuilder(requireContext()).apply {
|
is VerificationCodeRequestResult.Success -> Unit
|
||||||
setMessage(getString(R.string.RegistrationActivity_the_number_you_specified_s_is_invalid, fragmentViewModel.phoneNumber?.toE164()))
|
|
||||||
setPositiveButton(android.R.string.ok, null)
|
is RegistrationSessionCreationResult.AttemptsExhausted,
|
||||||
show()
|
is VerificationCodeRequestResult.AttemptsExhausted -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_rate_limited_to_service))
|
||||||
|
|
||||||
|
is VerificationCodeRequestResult.ChallengeRequired -> {
|
||||||
|
handleChallenges(result.challenges)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
is VerificationCodeRequestResult.InvalidTransportModeFailure -> {
|
is VerificationCodeRequestResult.ExternalServiceFailure -> presentRemoteErrorDialog(getString(R.string.RegistrationActivity_unable_to_connect_to_service), skipToNextScreen)
|
||||||
MaterialAlertDialogBuilder(requireContext()).apply {
|
is VerificationCodeRequestResult.ImpossibleNumber -> {
|
||||||
setMessage(R.string.RegistrationActivity_we_couldnt_send_you_a_verification_code)
|
MaterialAlertDialogBuilder(requireContext()).apply {
|
||||||
setPositiveButton(R.string.RegistrationActivity_voice_call) { _, _ ->
|
setMessage(getString(R.string.RegistrationActivity_the_number_you_specified_s_is_invalid, fragmentViewModel.phoneNumber?.toE164()))
|
||||||
sharedViewModel.requestVerificationCall(requireContext(), ::handleErrorResponse)
|
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))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ class WelcomeFragment : LoggingFragment(R.layout.fragment_registration_welcome)
|
|||||||
}
|
}
|
||||||
Activity.RESULT_CANCELED -> {
|
Activity.RESULT_CANCELED -> {
|
||||||
Log.w(TAG, "Backup restoration canceled.")
|
Log.w(TAG, "Backup restoration canceled.")
|
||||||
findNavController().popBackStack()
|
|
||||||
}
|
}
|
||||||
else -> Log.w(TAG, "Backup restoration activity ended with unknown result code: $resultCode")
|
else -> Log.w(TAG, "Backup restoration activity ended with unknown result code: $resultCode")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user