kopia lustrzana https://github.com/ryukoposting/Signal-Android
Ensure change number operation status before returning to normal app usage.
rodzic
d8c82add78
commit
7e7bbad788
|
@ -391,6 +391,10 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".components.settings.app.changenumber.ChangeNumberLockActivity"
|
||||
android:theme="@style/Signal.DayNight.NoActionBar"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".components.settings.conversation.ConversationSettingsActivity"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
||||
android:theme="@style/Signal.DayNight.ConversationSettings"
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.greenrobot.eventbus.EventBus;
|
|||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.core.util.tracing.Tracer;
|
||||
import org.signal.devicetransfer.TransferStatus;
|
||||
import org.thoughtcrime.securesms.components.settings.app.changenumber.ChangeNumberLockActivity;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.devicetransfer.olddevice.OldDeviceTransferActivity;
|
||||
|
@ -50,6 +51,7 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
|
|||
private static final int STATE_CREATE_SIGNAL_PIN = 7;
|
||||
private static final int STATE_TRANSFER_ONGOING = 8;
|
||||
private static final int STATE_TRANSFER_LOCKED = 9;
|
||||
private static final int STATE_CHANGE_NUMBER_LOCK = 10;
|
||||
|
||||
private SignalServiceNetworkAccess networkAccess;
|
||||
private BroadcastReceiver clearKeyReceiver;
|
||||
|
@ -153,6 +155,7 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
|
|||
case STATE_CREATE_PROFILE_NAME: return getCreateProfileNameIntent();
|
||||
case STATE_TRANSFER_ONGOING: return getOldDeviceTransferIntent();
|
||||
case STATE_TRANSFER_LOCKED: return getOldDeviceTransferLockedIntent();
|
||||
case STATE_CHANGE_NUMBER_LOCK: return getChangeNumberLockIntent();
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
@ -176,6 +179,8 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
|
|||
return STATE_TRANSFER_ONGOING;
|
||||
} else if (SignalStore.misc().isOldDeviceTransferLocked()) {
|
||||
return STATE_TRANSFER_LOCKED;
|
||||
} else if (SignalStore.misc().isChangeNumberLocked() && getClass() != ChangeNumberLockActivity.class) {
|
||||
return STATE_CHANGE_NUMBER_LOCK;
|
||||
} else {
|
||||
return STATE_NORMAL;
|
||||
}
|
||||
|
@ -243,6 +248,10 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
|
|||
return MainActivity.clearTop(this);
|
||||
}
|
||||
|
||||
private Intent getChangeNumberLockIntent() {
|
||||
return ChangeNumberLockActivity.createIntent(this);
|
||||
}
|
||||
|
||||
private Intent getRoutedIntent(Class<?> destination, @Nullable Intent nextIntent) {
|
||||
final Intent intent = new Intent(this, destination);
|
||||
if (nextIntent != null) intent.putExtra("next_intent", nextIntent);
|
||||
|
|
|
@ -2,12 +2,14 @@ package org.thoughtcrime.securesms.components.settings.app.changenumber
|
|||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.settings.app.changenumber.ChangeNumberUtil.changeNumberSuccess
|
||||
import org.thoughtcrime.securesms.components.settings.app.changenumber.ChangeNumberUtil.getCaptchaArguments
|
||||
import org.thoughtcrime.securesms.components.settings.app.changenumber.ChangeNumberUtil.getViewModel
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.registration.fragments.BaseEnterCodeFragment
|
||||
|
||||
class ChangeNumberEnterCodeFragment : BaseEnterCodeFragment<ChangeNumberViewModel>(R.layout.fragment_change_number_enter_code) {
|
||||
|
@ -17,9 +19,26 @@ class ChangeNumberEnterCodeFragment : BaseEnterCodeFragment<ChangeNumberViewMode
|
|||
|
||||
val toolbar: Toolbar = view.findViewById(R.id.toolbar)
|
||||
toolbar.title = viewModel.number.fullFormattedNumber
|
||||
toolbar.setNavigationOnClickListener { findNavController().navigateUp() }
|
||||
toolbar.setNavigationOnClickListener { navigateUp() }
|
||||
|
||||
view.findViewById<View>(R.id.verify_header).setOnClickListener(null)
|
||||
|
||||
requireActivity().onBackPressedDispatcher.addCallback(
|
||||
viewLifecycleOwner,
|
||||
object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
navigateUp()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun navigateUp() {
|
||||
if (SignalStore.misc().isChangeNumberLocked) {
|
||||
startActivity(ChangeNumberLockActivity.createIntent(requireContext()))
|
||||
} else {
|
||||
findNavController().navigateUp()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getViewModel(): ChangeNumberViewModel {
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
package org.thoughtcrime.securesms.components.settings.app.changenumber
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.MainActivity
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.logsubmit.SubmitDebugLogActivity
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter
|
||||
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme
|
||||
import org.thoughtcrime.securesms.util.LifecycleDisposable
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import java.util.Objects
|
||||
|
||||
private val TAG: String = Log.tag(ChangeNumberLockActivity::class.java)
|
||||
|
||||
/**
|
||||
* A captive activity that can determine if an interrupted/erred change number request
|
||||
* caused a disparity between the server and our locally stored number.
|
||||
*/
|
||||
class ChangeNumberLockActivity : PassphraseRequiredActivity() {
|
||||
|
||||
private val dynamicTheme: DynamicTheme = DynamicNoActionBarTheme()
|
||||
private val disposables: LifecycleDisposable = LifecycleDisposable()
|
||||
private lateinit var changeNumberRepository: ChangeNumberRepository
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
|
||||
dynamicTheme.onCreate(this)
|
||||
disposables.bindTo(lifecycle)
|
||||
|
||||
setContentView(R.layout.activity_change_number_lock)
|
||||
|
||||
changeNumberRepository = ChangeNumberRepository(applicationContext)
|
||||
checkWhoAmI()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
dynamicTheme.onResume(this)
|
||||
}
|
||||
|
||||
override fun onBackPressed() = Unit
|
||||
|
||||
private fun checkWhoAmI() {
|
||||
disposables.add(
|
||||
changeNumberRepository.whoAmI()
|
||||
.flatMap { whoAmI ->
|
||||
if (Objects.equals(whoAmI.number, TextSecurePreferences.getLocalNumber(this))) {
|
||||
Log.i(TAG, "Local and remote numbers match, nothing needs to be done.")
|
||||
Single.just(false)
|
||||
} else {
|
||||
Log.i(TAG, "Local (${TextSecurePreferences.getLocalNumber(this)}) and remote (${whoAmI.number}) numbers do not match, updating local.")
|
||||
changeNumberRepository.changeLocalNumber(whoAmI.number)
|
||||
.map { true }
|
||||
}
|
||||
}
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribeBy(onSuccess = { onChangeStatusConfirmed() }, onError = this::onFailedToGetChangeNumberStatus)
|
||||
)
|
||||
}
|
||||
|
||||
private fun onChangeStatusConfirmed() {
|
||||
SignalStore.misc().unlockChangeNumber()
|
||||
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.ChangeNumberLockActivity__change_status_confirmed)
|
||||
.setMessage(getString(R.string.ChangeNumberLockActivity__your_number_has_been_confirmed_as_s, PhoneNumberFormatter.prettyPrint(TextSecurePreferences.getLocalNumber(this))))
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
startActivity(MainActivity.clearTop(this))
|
||||
finish()
|
||||
}
|
||||
.setCancelable(false)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun onFailedToGetChangeNumberStatus(error: Throwable) {
|
||||
Log.w(TAG, "Unable to determine status of change number", error)
|
||||
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.ChangeNumberLockActivity__change_status_unconfirmed)
|
||||
.setMessage(getString(R.string.ChangeNumberLockActivity__we_could_not_determine_the_status_of_your_change_number_request, error.javaClass.simpleName))
|
||||
.setPositiveButton(R.string.ChangeNumberLockActivity__retry) { _, _ -> checkWhoAmI() }
|
||||
.setNegativeButton(R.string.ChangeNumberLockActivity__leave) { _, _ -> finish() }
|
||||
.setNeutralButton(R.string.ChangeNumberLockActivity__submit_debug_log) { _, _ ->
|
||||
startActivity(Intent(this, SubmitDebugLogActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
.setCancelable(false)
|
||||
.show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createIntent(context: Context): Intent {
|
||||
return Intent(context, ChangeNumberLockActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.components.settings.app.changenumber
|
|||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
@ -20,7 +21,16 @@ class ChangeNumberRegistrationLockFragment : BaseRegistrationLockFragment(R.layo
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val toolbar: Toolbar = view.findViewById(R.id.toolbar)
|
||||
toolbar.setNavigationOnClickListener { findNavController().navigateUp() }
|
||||
toolbar.setNavigationOnClickListener { navigateUp() }
|
||||
|
||||
requireActivity().onBackPressedDispatcher.addCallback(
|
||||
viewLifecycleOwner,
|
||||
object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
navigateUp()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun getViewModel(): BaseRegistrationViewModel {
|
||||
|
@ -60,4 +70,12 @@ class ChangeNumberRegistrationLockFragment : BaseRegistrationLockFragment(R.layo
|
|||
body
|
||||
)
|
||||
}
|
||||
|
||||
private fun navigateUp() {
|
||||
if (SignalStore.misc().isChangeNumberLocked) {
|
||||
startActivity(ChangeNumberLockActivity.createIntent(requireContext()))
|
||||
} else {
|
||||
findNavController().navigateUp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.whispersystems.signalservice.api.KbsPinData
|
|||
import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse
|
||||
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse
|
||||
import org.whispersystems.signalservice.internal.push.WhoAmIResponse
|
||||
|
||||
private val TAG: String = Log.tag(ChangeNumberRepository::class.java)
|
||||
|
||||
|
@ -51,12 +52,18 @@ class ChangeNumberRepository(private val context: Context) {
|
|||
}.subscribeOn(Schedulers.io())
|
||||
}
|
||||
|
||||
@Suppress("UsePropertyAccessSyntax")
|
||||
fun whoAmI(): Single<WhoAmIResponse> {
|
||||
return Single.fromCallable { ApplicationDependencies.getSignalServiceAccountManager().getWhoAmI() }
|
||||
.subscribeOn(Schedulers.io())
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun changeLocalNumber(e164: String): Single<Unit> {
|
||||
TextSecurePreferences.setLocalNumber(context, e164)
|
||||
|
||||
DatabaseFactory.getRecipientDatabase(context).updateSelfPhone(e164)
|
||||
|
||||
TextSecurePreferences.setLocalNumber(context, e164)
|
||||
|
||||
ApplicationDependencies.closeConnections()
|
||||
ApplicationDependencies.getIncomingMessageObserver()
|
||||
|
||||
|
|
|
@ -12,18 +12,21 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil
|
|||
import io.reactivex.rxjava3.core.Single
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.pin.KbsRepository
|
||||
import org.thoughtcrime.securesms.pin.TokenData
|
||||
import org.thoughtcrime.securesms.registration.VerifyAccountRepository
|
||||
import org.thoughtcrime.securesms.registration.VerifyAccountResponseProcessor
|
||||
import org.thoughtcrime.securesms.registration.VerifyAccountResponseWithoutKbs
|
||||
import org.thoughtcrime.securesms.registration.VerifyCodeWithRegistrationLockResponseProcessor
|
||||
import org.thoughtcrime.securesms.registration.VerifyProcessor
|
||||
import org.thoughtcrime.securesms.registration.viewmodel.BaseRegistrationViewModel
|
||||
import org.thoughtcrime.securesms.registration.viewmodel.NumberViewState
|
||||
import org.thoughtcrime.securesms.util.DefaultValueLiveData
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse
|
||||
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse
|
||||
import java.util.Objects
|
||||
|
||||
private val TAG: String = Log.tag(ChangeNumberViewModel::class.java)
|
||||
|
||||
|
@ -104,6 +107,35 @@ class ChangeNumberViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
override fun verifyCodeWithoutRegistrationLock(code: String): Single<VerifyAccountResponseProcessor> {
|
||||
return super.verifyCodeWithoutRegistrationLock(code)
|
||||
.doOnSubscribe { SignalStore.misc().lockChangeNumber() }
|
||||
.flatMap(this::attemptToUnlockChangeNumber)
|
||||
}
|
||||
|
||||
override fun verifyCodeAndRegisterAccountWithRegistrationLock(pin: String): Single<VerifyCodeWithRegistrationLockResponseProcessor> {
|
||||
return super.verifyCodeAndRegisterAccountWithRegistrationLock(pin)
|
||||
.doOnSubscribe { SignalStore.misc().lockChangeNumber() }
|
||||
.flatMap(this::attemptToUnlockChangeNumber)
|
||||
}
|
||||
|
||||
private fun <T : VerifyProcessor> attemptToUnlockChangeNumber(processor: T): Single<T> {
|
||||
return if (processor.hasResult() || processor.isServerSentError()) {
|
||||
SignalStore.misc().unlockChangeNumber()
|
||||
Single.just(processor)
|
||||
} else {
|
||||
changeNumberRepository.whoAmI()
|
||||
.map { whoAmI ->
|
||||
if (Objects.equals(whoAmI.number, localNumber)) {
|
||||
Log.i(TAG, "Local and remote numbers match, we can unlock.")
|
||||
SignalStore.misc().unlockChangeNumber()
|
||||
}
|
||||
processor
|
||||
}
|
||||
.onErrorReturn { processor }
|
||||
}
|
||||
}
|
||||
|
||||
override fun verifyAccountWithoutRegistrationLock(): Single<ServiceResponse<VerifyAccountResponse>> {
|
||||
return changeNumberRepository.changeNumber(textCodeEntered, number.e164Number)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ public final class MiscellaneousValues extends SignalStoreValues {
|
|||
private static final String CLIENT_DEPRECATED = "misc.client_deprecated";
|
||||
private static final String OLD_DEVICE_TRANSFER_LOCKED = "misc.old_device.transfer.locked";
|
||||
private static final String HAS_EVER_HAD_AN_AVATAR = "misc.has.ever.had.an.avatar";
|
||||
private static final String CHANGE_NUMBER_LOCK = "misc.change_number.lock";
|
||||
|
||||
MiscellaneousValues(@NonNull KeyValueStore store) {
|
||||
super(store);
|
||||
|
@ -97,4 +98,16 @@ public final class MiscellaneousValues extends SignalStoreValues {
|
|||
public void markHasEverHadAnAvatar() {
|
||||
putBoolean(HAS_EVER_HAD_AN_AVATAR, true);
|
||||
}
|
||||
|
||||
public boolean isChangeNumberLocked() {
|
||||
return getBoolean(CHANGE_NUMBER_LOCK, false);
|
||||
}
|
||||
|
||||
public void lockChangeNumber() {
|
||||
putBoolean(CHANGE_NUMBER_LOCK, true);
|
||||
}
|
||||
|
||||
public void unlockChangeNumber() {
|
||||
putBoolean(CHANGE_NUMBER_LOCK, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.thoughtcrime.securesms.registration
|
||||
|
||||
import org.thoughtcrime.securesms.pin.TokenData
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse
|
||||
import org.whispersystems.signalservice.internal.ServiceResponseProcessor
|
||||
import org.whispersystems.signalservice.internal.push.LockedException
|
||||
|
@ -9,7 +10,9 @@ import org.whispersystems.signalservice.internal.push.VerifyAccountResponse
|
|||
/**
|
||||
* Process responses from attempting to verify an account for use in account registration.
|
||||
*/
|
||||
sealed class VerifyAccountResponseProcessor(response: ServiceResponse<VerifyAccountResponse>) : ServiceResponseProcessor<VerifyAccountResponse>(response) {
|
||||
sealed class VerifyAccountResponseProcessor(
|
||||
response: ServiceResponse<VerifyAccountResponse>
|
||||
) : ServiceResponseProcessor<VerifyAccountResponse>(response), VerifyProcessor {
|
||||
|
||||
open val tokenData: TokenData? = null
|
||||
|
||||
|
@ -33,6 +36,10 @@ sealed class VerifyAccountResponseProcessor(response: ServiceResponse<VerifyAcco
|
|||
return error as LockedException
|
||||
}
|
||||
|
||||
override fun isServerSentError(): Boolean {
|
||||
return error is NonSuccessfulResponseCodeException
|
||||
}
|
||||
|
||||
abstract fun isKbsLocked(): Boolean
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.thoughtcrime.securesms.pin.KeyBackupSystemWrongPinException
|
|||
import org.thoughtcrime.securesms.pin.TokenData
|
||||
import org.thoughtcrime.securesms.registration.VerifyAccountRepository.VerifyAccountWithRegistrationLockResponse
|
||||
import org.whispersystems.signalservice.api.KeyBackupSystemNoDataException
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse
|
||||
import org.whispersystems.signalservice.internal.ServiceResponseProcessor
|
||||
import org.whispersystems.signalservice.internal.contacts.entities.TokenResponse
|
||||
|
@ -16,7 +17,7 @@ import org.whispersystems.signalservice.internal.push.VerifyAccountResponse
|
|||
class VerifyCodeWithRegistrationLockResponseProcessor(
|
||||
response: ServiceResponse<VerifyAccountWithRegistrationLockResponse>,
|
||||
val token: TokenData
|
||||
) : ServiceResponseProcessor<VerifyAccountWithRegistrationLockResponse>(response) {
|
||||
) : ServiceResponseProcessor<VerifyAccountWithRegistrationLockResponse>(response), VerifyProcessor {
|
||||
|
||||
public override fun rateLimit(): Boolean {
|
||||
return super.rateLimit()
|
||||
|
@ -45,4 +46,10 @@ class VerifyCodeWithRegistrationLockResponseProcessor(
|
|||
|
||||
return VerifyCodeWithRegistrationLockResponseProcessor(ServiceResponse.coerceError(response), token)
|
||||
}
|
||||
|
||||
override fun isServerSentError(): Boolean {
|
||||
return error is NonSuccessfulResponseCodeException ||
|
||||
error is KeyBackupSystemWrongPinException ||
|
||||
error is KeyBackupSystemNoDataException
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package org.thoughtcrime.securesms.registration
|
||||
|
||||
interface VerifyProcessor {
|
||||
fun hasResult(): Boolean
|
||||
fun isServerSentError(): Boolean
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/change_number_lock_scroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:fillViewport="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/change_number_lock_hero"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_marginTop="@dimen/transfer_top_padding"
|
||||
app:layout_constraintBottom_toTopOf="@id/change_number_lock_header"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
app:layout_constraintVertical_bias="0"
|
||||
app:tint="@color/signal_alert_primary"
|
||||
app:srcCompat="@drawable/ic_alert" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/change_number_lock_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginTop="@dimen/transfer_item_spacing"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/AccountSettingsFragment__change_phone_number"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Title1"
|
||||
app:layout_constraintBottom_toTopOf="@id/change_number_lock_body"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/change_number_lock_hero" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/change_number_lock_body"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/ChangeNumberLockActivity__it_looks_like_you_tried_to_change_your_number_but_we_were_unable_to_determine_if_it_was_successful_rechecking_now"
|
||||
android:textAppearance="@style/TextAppearance.Signal.Body1"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/change_number_lock_header" />
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/change_phone_number_verify_progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/transfer_top_padding"
|
||||
android:indeterminate="true"
|
||||
app:indicatorColor="@color/signal_accent_primary"
|
||||
app:indicatorSize="48dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/change_number_lock_body" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</ScrollView>
|
|
@ -3531,6 +3531,16 @@
|
|||
<string name="ChangeNumberPinDiffersFragment__update_pin">Update PIN</string>
|
||||
<string name="ChangeNumberPinDiffersFragment__keep_old_pin_question">Keep old pin?</string>
|
||||
|
||||
<!-- ChangeNumberLockActivity -->
|
||||
<string name="ChangeNumberLockActivity__it_looks_like_you_tried_to_change_your_number_but_we_were_unable_to_determine_if_it_was_successful_rechecking_now">It looks like you tried to change your number but we were unable to determine if it was successful.\n\nRechecking now…</string>
|
||||
<string name="ChangeNumberLockActivity__change_status_confirmed">Change status confirmed</string>
|
||||
<string name="ChangeNumberLockActivity__your_number_has_been_confirmed_as_s">Your number has been confirmed as %1$s. If this is not your new number, please restart the change number process.</string>
|
||||
<string name="ChangeNumberLockActivity__change_status_unconfirmed">Change status unconfirmed</string>
|
||||
<string name="ChangeNumberLockActivity__we_could_not_determine_the_status_of_your_change_number_request">We could not determine the status of your change number request.\n\n(Error: %1$s)</string>
|
||||
<string name="ChangeNumberLockActivity__retry">Retry</string>
|
||||
<string name="ChangeNumberLockActivity__leave">Leave</string>
|
||||
<string name="ChangeNumberLockActivity__submit_debug_log">Submit debug log</string>
|
||||
|
||||
<!-- ChatsSettingsFragment -->
|
||||
<string name="ChatsSettingsFragment__keyboard">Keyboard</string>
|
||||
<string name="ChatsSettingsFragment__enter_key_sends">Enter key sends</string>
|
||||
|
|
|
@ -65,6 +65,7 @@ import org.whispersystems.signalservice.internal.push.RemoteConfigResponse;
|
|||
import org.whispersystems.signalservice.internal.push.RequestVerificationCodeResponse;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
|
||||
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse;
|
||||
import org.whispersystems.signalservice.internal.push.WhoAmIResponse;
|
||||
import org.whispersystems.signalservice.internal.push.http.ProfileCipherOutputStreamFactory;
|
||||
import org.whispersystems.signalservice.internal.storage.protos.ManifestRecord;
|
||||
import org.whispersystems.signalservice.internal.storage.protos.ReadOperation;
|
||||
|
@ -169,6 +170,10 @@ public class SignalServiceAccountManager {
|
|||
return this.pushServiceSocket.getOwnUuid();
|
||||
}
|
||||
|
||||
public WhoAmIResponse getWhoAmI() throws IOException {
|
||||
return this.pushServiceSocket.getWhoAmI();
|
||||
}
|
||||
|
||||
public KeyBackupService getKeyBackupService(KeyStore iasKeyStore,
|
||||
String enclaveName,
|
||||
byte[] serviceId,
|
||||
|
|
|
@ -328,6 +328,10 @@ public class PushServiceSocket {
|
|||
}
|
||||
}
|
||||
|
||||
public WhoAmIResponse getWhoAmI() throws IOException {
|
||||
return JsonUtil.fromJson(makeServiceRequest(WHO_AM_I, "GET", null), WhoAmIResponse.class);
|
||||
}
|
||||
|
||||
public VerifyAccountResponse verifyAccountCode(String verificationCode, String signalingKey, int registrationId, boolean fetchesMessages,
|
||||
String pin, String registrationLock,
|
||||
byte[] unidentifiedAccessKey, boolean unrestrictedUnidentifiedAccess,
|
||||
|
|
|
@ -6,7 +6,14 @@ public class WhoAmIResponse {
|
|||
@JsonProperty
|
||||
private String uuid;
|
||||
|
||||
@JsonProperty
|
||||
private String number;
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue