Quicksy: add restore backup menu item to 'enter phone number' activity

Daniel Gultsch created

Change summary

src/quicksy/java/eu/siacs/conversations/ui/EnterPhoneNumberActivity.java | 214 
src/quicksy/java/eu/siacs/conversations/ui/VerifyActivity.java           | 202 
src/quicksy/res/menu/verify_phone_number_menu.xml                        |   8 
3 files changed, 274 insertions(+), 150 deletions(-)

Detailed changes

src/quicksy/java/eu/siacs/conversations/ui/EnterPhoneNumberActivity.java 🔗

@@ -1,10 +1,10 @@
 package eu.siacs.conversations.ui;
 
+import static eu.siacs.conversations.utils.PermissionUtils.allGranted;
+
+import android.Manifest;
 import android.app.AlertDialog;
 import android.content.Intent;
-
-import androidx.annotation.NonNull;
-import androidx.databinding.DataBindingUtil;
 import android.os.Bundle;
 import android.text.Editable;
 import android.text.Html;
@@ -12,11 +12,13 @@ import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
 import android.view.View;
 import android.widget.EditText;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
+import android.widget.Toast;
+import androidx.annotation.NonNull;
+import androidx.databinding.DataBindingUtil;
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.databinding.ActivityEnterNumberBinding;
@@ -30,57 +32,73 @@ import eu.siacs.conversations.utils.PhoneNumberUtilWrapper;
 import io.michaelrocks.libphonenumber.android.NumberParseException;
 import io.michaelrocks.libphonenumber.android.PhoneNumberUtil;
 import io.michaelrocks.libphonenumber.android.Phonenumber;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicBoolean;
 
-public class EnterPhoneNumberActivity extends XmppActivity implements QuickConversationsService.OnVerificationRequested {
+public class EnterPhoneNumberActivity extends XmppActivity
+        implements QuickConversationsService.OnVerificationRequested {
 
     private static final int REQUEST_CHOOSE_COUNTRY = 0x1234;
+    private static final int REQUEST_IMPORT_BACKUP = 0x63fb;
 
     private ActivityEnterNumberBinding binding;
 
     private final AtomicBoolean redirectInProgress = new AtomicBoolean(false);
 
     private String region = null;
-    private final TextWatcher countryCodeTextWatcher = new TextWatcher() {
-        @Override
-        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-
-        }
-
-        @Override
-        public void onTextChanged(CharSequence s, int start, int before, int count) {
-
-        }
-
-        @Override
-        public void afterTextChanged(Editable editable) {
-            final String text = editable.toString();
-            try {
-                final int oldCode = region != null ? PhoneNumberUtilWrapper.getInstance(EnterPhoneNumberActivity.this).getCountryCodeForRegion(region) : 0;
-                final int code = Integer.parseInt(text);
-                if (oldCode != code) {
-                    region = PhoneNumberUtilWrapper.getInstance(EnterPhoneNumberActivity.this).getRegionCodeForCountryCode(code);
+    private final TextWatcher countryCodeTextWatcher =
+            new TextWatcher() {
+                @Override
+                public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+                @Override
+                public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+                @Override
+                public void afterTextChanged(Editable editable) {
+                    final String text = editable.toString();
+                    try {
+                        final int oldCode =
+                                region != null
+                                        ? PhoneNumberUtilWrapper.getInstance(
+                                                        EnterPhoneNumberActivity.this)
+                                                .getCountryCodeForRegion(region)
+                                        : 0;
+                        final int code = Integer.parseInt(text);
+                        if (oldCode != code) {
+                            region =
+                                    PhoneNumberUtilWrapper.getInstance(
+                                                    EnterPhoneNumberActivity.this)
+                                            .getRegionCodeForCountryCode(code);
+                        }
+                        if ("ZZ".equals(region)) {
+                            binding.country.setText(
+                                    TextUtils.isEmpty(text)
+                                            ? R.string.choose_a_country
+                                            : R.string.invalid_country_code);
+                        } else {
+                            binding.number.requestFocus();
+                            binding.country.setText(
+                                    PhoneNumberUtilWrapper.getCountryForCode(region));
+                        }
+                    } catch (NumberFormatException e) {
+                        binding.country.setText(
+                                TextUtils.isEmpty(text)
+                                        ? R.string.choose_a_country
+                                        : R.string.invalid_country_code);
+                    }
                 }
-                if ("ZZ".equals(region)) {
-                    binding.country.setText(TextUtils.isEmpty(text) ? R.string.choose_a_country : R.string.invalid_country_code);
-                } else {
-                    binding.number.requestFocus();
-                    binding.country.setText(PhoneNumberUtilWrapper.getCountryForCode(region));
-                }
-            } catch (NumberFormatException e) {
-                binding.country.setText(TextUtils.isEmpty(text) ? R.string.choose_a_country : R.string.invalid_country_code);
-            }
-        }
-    };
+            };
     private boolean requestingVerification = false;
 
     @Override
-    protected void refreshUiReal() {
-
-    }
+    protected void refreshUiReal() {}
 
     @Override
     public void onBackendConnected() {
-        xmppConnectionService.getQuickConversationsService().addOnVerificationRequestedListener(this);
+        xmppConnectionService
+                .getQuickConversationsService()
+                .addOnVerificationRequestedListener(this);
         final Account account = AccountUtils.getFirst(xmppConnectionService);
         if (account != null) {
             runOnUiThread(this::performRedirectToVerificationActivity);
@@ -92,7 +110,9 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
         super.onCreate(savedInstanceState);
 
         String region = savedInstanceState != null ? savedInstanceState.getString("region") : null;
-        boolean requestingVerification = savedInstanceState != null && savedInstanceState.getBoolean("requesting_verification", false);
+        boolean requestingVerification =
+                savedInstanceState != null
+                        && savedInstanceState.getBoolean("requesting_verification", false);
         if (region != null) {
             this.region = region;
         } else {
@@ -100,31 +120,73 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
         }
 
         this.binding = DataBindingUtil.setContentView(this, R.layout.activity_enter_number);
-        this.binding.countryCode.setCompoundDrawables(new TextDrawable(this.binding.countryCode, "+"), null, null, null);
+        this.binding.countryCode.setCompoundDrawables(
+                new TextDrawable(this.binding.countryCode, "+"), null, null, null);
         this.binding.country.setOnClickListener(this::onSelectCountryClick);
         this.binding.next.setOnClickListener(this::onNextClick);
         Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
         setSupportActionBar(this.binding.toolbar);
         this.binding.countryCode.addTextChangedListener(this.countryCodeTextWatcher);
-        this.binding.countryCode.setText(String.valueOf(PhoneNumberUtilWrapper.getInstance(this).getCountryCodeForRegion(this.region)));
-        this.binding.number.setOnKeyListener((v, keyCode, event) -> {
-            if (event.getAction() != KeyEvent.ACTION_DOWN) {
-                return false;
+        this.binding.countryCode.setText(
+                String.valueOf(
+                        PhoneNumberUtilWrapper.getInstance(this)
+                                .getCountryCodeForRegion(this.region)));
+        this.binding.number.setOnKeyListener(
+                (v, keyCode, event) -> {
+                    if (event.getAction() != KeyEvent.ACTION_DOWN) {
+                        return false;
+                    }
+                    final EditText editText = (EditText) v;
+                    final boolean cursorAtZero =
+                            editText.getSelectionEnd() == 0 && editText.getSelectionStart() == 0;
+                    if (keyCode == KeyEvent.KEYCODE_DEL
+                            && (cursorAtZero || editText.getText().length() == 0)) {
+                        final Editable countryCode = this.binding.countryCode.getText();
+                        if (countryCode.length() > 0) {
+                            countryCode.delete(countryCode.length() - 1, countryCode.length());
+                            this.binding.countryCode.setSelection(countryCode.length());
+                        }
+                        this.binding.countryCode.requestFocus();
+                        return true;
+                    }
+                    return false;
+                });
+        setRequestingVerificationState(requestingVerification);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(final Menu menu) {
+        getMenuInflater().inflate(R.menu.verify_phone_number_menu, menu);
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem item) {
+        if (item.getItemId() == R.id.action_import_backup) {
+            if (hasStoragePermission(REQUEST_IMPORT_BACKUP)) {
+                startActivity(new Intent(this, ImportBackupActivity.class));
             }
-            final EditText editText = (EditText) v;
-            final boolean cursorAtZero = editText.getSelectionEnd() == 0 && editText.getSelectionStart() == 0;
-            if (keyCode == KeyEvent.KEYCODE_DEL && (cursorAtZero || editText.getText().length() == 0)) {
-                final Editable countryCode = this.binding.countryCode.getText();
-                if (countryCode.length() > 0) {
-                    countryCode.delete(countryCode.length() - 1, countryCode.length());
-                    this.binding.countryCode.setSelection(countryCode.length());
+            return true;
+        } else {
+            return super.onOptionsItemSelected(item);
+        }
+    }
+
+    @Override
+    public void onRequestPermissionsResult(
+            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+        UriHandlerActivity.onRequestPermissionResult(this, requestCode, grantResults);
+        if (grantResults.length > 0) {
+            if (allGranted(grantResults)) {
+                if (requestCode == REQUEST_IMPORT_BACKUP) {
+                    startActivity(new Intent(this, ImportBackupActivity.class));
                 }
-                this.binding.countryCode.requestFocus();
-                return true;
+            } else if (Arrays.asList(permissions)
+                    .contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+                Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
             }
-            return false;
-        });
-        setRequestingVerificationState(requestingVerification);
+        }
     }
 
     @Override
@@ -139,7 +201,9 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
     @Override
     public void onStop() {
         if (xmppConnectionService != null) {
-            xmppConnectionService.getQuickConversationsService().removeOnVerificationRequestedListener(this);
+            xmppConnectionService
+                    .getQuickConversationsService()
+                    .removeOnVerificationRequestedListener(this);
         }
         super.onStop();
     }
@@ -149,18 +213,26 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
         try {
             final Editable number = this.binding.number.getText();
             final String input = number.toString();
-            final Phonenumber.PhoneNumber phoneNumber = PhoneNumberUtilWrapper.getInstance(this).parse(input, region);
+            final Phonenumber.PhoneNumber phoneNumber =
+                    PhoneNumberUtilWrapper.getInstance(this).parse(input, region);
             this.binding.countryCode.setText(String.valueOf(phoneNumber.getCountryCode()));
             number.clear();
             number.append(String.valueOf(phoneNumber.getNationalNumber()));
-            final String formattedPhoneNumber = PhoneNumberUtilWrapper.getInstance(this).format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL).replace(' ','\u202F');
+            final String formattedPhoneNumber =
+                    PhoneNumberUtilWrapper.getInstance(this)
+                            .format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL)
+                            .replace(' ', '\u202F');
 
             if (PhoneNumberUtilWrapper.getInstance(this).isValidNumber(phoneNumber)) {
-                builder.setMessage(Html.fromHtml(getString(R.string.we_will_be_verifying, formattedPhoneNumber)));
+                builder.setMessage(
+                        Html.fromHtml(
+                                getString(R.string.we_will_be_verifying, formattedPhoneNumber)));
                 builder.setNegativeButton(R.string.edit, null);
-                builder.setPositiveButton(R.string.ok, (dialog, which) -> onPhoneNumberEntered(phoneNumber));
+                builder.setPositiveButton(
+                        R.string.ok, (dialog, which) -> onPhoneNumberEntered(phoneNumber));
             } else {
-                builder.setMessage(getString(R.string.not_a_valid_phone_number, formattedPhoneNumber));
+                builder.setMessage(
+                        getString(R.string.not_a_valid_phone_number, formattedPhoneNumber));
                 builder.setPositiveButton(R.string.ok, null);
             }
             Log.d(Config.LOGTAG, phoneNumber.toString());
@@ -199,7 +271,8 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
             final String region = data.getStringExtra("region");
             if (region != null) {
                 this.region = region;
-                final int countryCode = PhoneNumberUtilWrapper.getInstance(this).getCountryCodeForRegion(region);
+                final int countryCode =
+                        PhoneNumberUtilWrapper.getInstance(this).getCountryCodeForRegion(region);
                 this.binding.countryCode.setText(String.valueOf(countryCode));
             }
         }
@@ -223,10 +296,11 @@ public class EnterPhoneNumberActivity extends XmppActivity implements QuickConve
 
     @Override
     public void onVerificationRequestFailed(int code) {
-        runOnUiThread(() -> {
-            setRequestingVerificationState(false);
-            ApiDialogHelper.createError(this, code).show();
-        });
+        runOnUiThread(
+                () -> {
+                    setRequestingVerificationState(false);
+                    ApiDialogHelper.createError(this, code).show();
+                });
     }
 
     @Override

src/quicksy/java/eu/siacs/conversations/ui/VerifyActivity.java 🔗

@@ -13,12 +13,9 @@ import android.os.Handler;
 import android.os.SystemClock;
 import android.text.Html;
 import android.view.View;
-
 import androidx.databinding.DataBindingUtil;
-
 import com.google.android.material.dialog.MaterialAlertDialogBuilder;
 import com.google.android.material.snackbar.Snackbar;
-
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.databinding.ActivityVerifyBinding;
 import eu.siacs.conversations.entities.Account;
@@ -28,12 +25,13 @@ import eu.siacs.conversations.ui.util.PinEntryWrapper;
 import eu.siacs.conversations.utils.AccountUtils;
 import eu.siacs.conversations.utils.PhoneNumberUtilWrapper;
 import eu.siacs.conversations.utils.TimeFrameUtils;
-
 import io.michaelrocks.libphonenumber.android.NumberParseException;
-
 import java.util.concurrent.atomic.AtomicBoolean;
 
-public class VerifyActivity extends XmppActivity implements ClipboardManager.OnPrimaryClipChangedListener, QuickConversationsService.OnVerification, QuickConversationsService.OnVerificationRequested {
+public class VerifyActivity extends XmppActivity
+        implements ClipboardManager.OnPrimaryClipChangedListener,
+                QuickConversationsService.OnVerification,
+                QuickConversationsService.OnVerificationRequested {
 
     public static final String EXTRA_RETRY_SMS_AFTER = "retry_sms_after";
     private static final String EXTRA_RETRY_VERIFICATION_AFTER = "retry_verification_after";
@@ -46,23 +44,25 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
     private boolean verifying = false;
     private boolean requestingVerification = false;
     private long retrySmsAfter = 0;
-    private final Runnable SMS_TIMEOUT_UPDATER = new Runnable() {
-        @Override
-        public void run() {
-            if (setTimeoutLabelInResendButton()) {
-                mHandler.postDelayed(this, 300);
-            }
-        }
-    };
+    private final Runnable SMS_TIMEOUT_UPDATER =
+            new Runnable() {
+                @Override
+                public void run() {
+                    if (setTimeoutLabelInResendButton()) {
+                        mHandler.postDelayed(this, 300);
+                    }
+                }
+            };
     private long retryVerificationAfter = 0;
-    private final Runnable VERIFICATION_TIMEOUT_UPDATER = new Runnable() {
-        @Override
-        public void run() {
-            if (setTimeoutLabelInNextButton()) {
-                mHandler.postDelayed(this, 300);
-            }
-        }
-    };
+    private final Runnable VERIFICATION_TIMEOUT_UPDATER =
+            new Runnable() {
+                @Override
+                public void run() {
+                    if (setTimeoutLabelInNextButton()) {
+                        mHandler.postDelayed(this, 300);
+                    }
+                }
+            };
     private final AtomicBoolean redirectInProgress = new AtomicBoolean(false);
 
     private boolean setTimeoutLabelInResendButton() {
@@ -70,7 +70,10 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
             long remaining = retrySmsAfter - SystemClock.elapsedRealtime();
             if (remaining >= 0) {
                 binding.resendSms.setEnabled(false);
-                binding.resendSms.setText(getString(R.string.resend_sms_in, TimeFrameUtils.resolve(VerifyActivity.this, remaining)));
+                binding.resendSms.setText(
+                        getString(
+                                R.string.resend_sms_in,
+                                TimeFrameUtils.resolve(VerifyActivity.this, remaining)));
                 return true;
             }
         }
@@ -84,7 +87,10 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
             long remaining = retryVerificationAfter - SystemClock.elapsedRealtime();
             if (remaining >= 0) {
                 binding.next.setEnabled(false);
-                binding.next.setText(getString(R.string.wait_x, TimeFrameUtils.resolve(VerifyActivity.this, remaining)));
+                binding.next.setText(
+                        getString(
+                                R.string.wait_x,
+                                TimeFrameUtils.resolve(VerifyActivity.this, remaining)));
                 return true;
             }
         }
@@ -97,11 +103,20 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
     protected void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         String pin = savedInstanceState != null ? savedInstanceState.getString("pin") : null;
-        boolean verifying = savedInstanceState != null && savedInstanceState.getBoolean("verifying");
-        boolean requestingVerification = savedInstanceState != null && savedInstanceState.getBoolean("requesting_verification", false);
+        boolean verifying =
+                savedInstanceState != null && savedInstanceState.getBoolean("verifying");
+        boolean requestingVerification =
+                savedInstanceState != null
+                        && savedInstanceState.getBoolean("requesting_verification", false);
         this.pasted = savedInstanceState != null ? savedInstanceState.getString("pasted") : null;
-        this.retrySmsAfter = savedInstanceState != null ? savedInstanceState.getLong(EXTRA_RETRY_SMS_AFTER, 0L) : 0L;
-        this.retryVerificationAfter = savedInstanceState != null ? savedInstanceState.getLong(EXTRA_RETRY_VERIFICATION_AFTER, 0L) : 0L;
+        this.retrySmsAfter =
+                savedInstanceState != null
+                        ? savedInstanceState.getLong(EXTRA_RETRY_SMS_AFTER, 0L)
+                        : 0L;
+        this.retryVerificationAfter =
+                savedInstanceState != null
+                        ? savedInstanceState.getLong(EXTRA_RETRY_VERIFICATION_AFTER, 0L)
+                        : 0L;
         this.binding = DataBindingUtil.setContentView(this, R.layout.activity_verify);
         Activities.setStatusAndNavigationBarColors(this, binding.getRoot());
         setSupportActionBar(this.binding.toolbar);
@@ -126,11 +141,13 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
         if (this.account != null) {
             final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
             builder.setMessage(R.string.abort_registration_procedure);
-            builder.setPositiveButton(R.string.yes, (dialog, which) -> {
-                xmppConnectionService.deleteAccount(account);
-                startActivity(intent);
-                finish();
-            });
+            builder.setPositiveButton(
+                    R.string.yes,
+                    (dialog, which) -> {
+                        xmppConnectionService.deleteAccount(account);
+                        startActivity(intent);
+                        finish();
+                    });
             builder.setNegativeButton(R.string.no, null);
             builder.create().show();
         } else {
@@ -156,7 +173,10 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
 
     private void onResendSmsButton(View view) {
         try {
-            xmppConnectionService.getQuickConversationsService().requestVerification(PhoneNumberUtilWrapper.toPhoneNumber(this, account.getJid()));
+            xmppConnectionService
+                    .getQuickConversationsService()
+                    .requestVerification(
+                            PhoneNumberUtilWrapper.toPhoneNumber(this, account.getJid()));
             setRequestingVerificationState(true);
         } catch (NumberParseException e) {
 
@@ -182,29 +202,35 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
         } else {
             setTimeoutLabelInResendButton();
         }
-
     }
 
     @Override
-    protected void refreshUiReal() {
-
-    }
+    protected void refreshUiReal() {}
 
     @Override
     public void onBackendConnected() {
         xmppConnectionService.getQuickConversationsService().addOnVerificationListener(this);
-        xmppConnectionService.getQuickConversationsService().addOnVerificationRequestedListener(this);
+        xmppConnectionService
+                .getQuickConversationsService()
+                .addOnVerificationRequestedListener(this);
         this.account = AccountUtils.getFirst(xmppConnectionService);
         if (this.account == null) {
             return;
         }
-        if (!account.isOptionSet(Account.OPTION_UNVERIFIED) && !account.isOptionSet(Account.OPTION_DISABLED)) {
+        if (!account.isOptionSet(Account.OPTION_UNVERIFIED)
+                && !account.isOptionSet(Account.OPTION_DISABLED)) {
             runOnUiThread(this::performPostVerificationRedirect);
             return;
         }
-        this.binding.weHaveSent.setText(Html.fromHtml(getString(R.string.we_have_sent_you_an_sms_to_x, PhoneNumberUtilWrapper.toFormattedPhoneNumber(this, this.account.getJid()))));
+        this.binding.weHaveSent.setText(
+                Html.fromHtml(
+                        getString(
+                                R.string.we_have_sent_you_an_sms_to_x,
+                                PhoneNumberUtilWrapper.toFormattedPhoneNumber(
+                                        this, this.account.getJid()))));
         setVerifyingState(xmppConnectionService.getQuickConversationsService().isVerifying());
-        setRequestingVerificationState(xmppConnectionService.getQuickConversationsService().isRequestingVerification());
+        setRequestingVerificationState(
+                xmppConnectionService.getQuickConversationsService().isRequestingVerification());
     }
 
     @Override
@@ -225,7 +251,10 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
         super.onStart();
         clipboardManager.addPrimaryClipChangedListener(this);
         final Intent intent = getIntent();
-        this.retrySmsAfter = intent != null ? intent.getLongExtra(EXTRA_RETRY_SMS_AFTER, this.retrySmsAfter) : this.retrySmsAfter;
+        this.retrySmsAfter =
+                intent != null
+                        ? intent.getLongExtra(EXTRA_RETRY_SMS_AFTER, this.retrySmsAfter)
+                        : this.retrySmsAfter;
         if (this.retrySmsAfter > 0) {
             mHandler.post(SMS_TIMEOUT_UPDATER);
         }
@@ -242,7 +271,9 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
         clipboardManager.removePrimaryClipChangedListener(this);
         if (xmppConnectionService != null) {
             xmppConnectionService.getQuickConversationsService().removeOnVerificationListener(this);
-            xmppConnectionService.getQuickConversationsService().removeOnVerificationRequestedListener(this);
+            xmppConnectionService
+                    .getQuickConversationsService()
+                    .removeOnVerificationRequestedListener(this);
         }
     }
 
@@ -250,14 +281,15 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
     public void onResume() {
         super.onResume();
         if (pinEntryWrapper.isEmpty()) {
-            //starting with Android P we need input focus
+            // starting with Android P we need input focus
             pinEntryWrapper.requestFocus();
             pastePinFromClipboard();
         }
     }
 
     private void pastePinFromClipboard() {
-        final ClipDescription description = clipboardManager != null ? clipboardManager.getPrimaryClipDescription() : null;
+        final ClipDescription description =
+                clipboardManager != null ? clipboardManager.getPrimaryClipDescription() : null;
         if (description != null && description.hasMimeType(MIMETYPE_TEXT_PLAIN)) {
             final ClipData primaryClip = clipboardManager.getPrimaryClip();
             if (primaryClip != null && primaryClip.getItemCount() > 0) {
@@ -265,7 +297,11 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
                 if (PinEntryWrapper.isValidPin(clip) && !clip.toString().equals(this.pasted)) {
                     this.pasted = clip.toString();
                     pinEntryWrapper.setPin(clip.toString());
-                    final Snackbar snackbar = Snackbar.make(binding.coordinator, R.string.possible_pin, Snackbar.LENGTH_LONG);
+                    final Snackbar snackbar =
+                            Snackbar.make(
+                                    binding.coordinator,
+                                    R.string.possible_pin,
+                                    Snackbar.LENGTH_LONG);
                     snackbar.setAction(R.string.undo, v -> pinEntryWrapper.clear());
                     snackbar.show();
                 }
@@ -291,17 +327,19 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
 
     @Override
     public void onVerificationFailed(final int code) {
-        runOnUiThread(() -> {
-            setVerifyingState(false);
-            if (code == 401 || code == 404) {
-                AlertDialog.Builder builder = new AlertDialog.Builder(this);
-                builder.setMessage(code == 404 ? R.string.pin_expired : R.string.incorrect_pin);
-                builder.setPositiveButton(R.string.ok, null);
-                builder.create().show();
-            } else {
-                ApiDialogHelper.createError(this, code).show();
-            }
-        });
+        runOnUiThread(
+                () -> {
+                    setVerifyingState(false);
+                    if (code == 401 || code == 404) {
+                        AlertDialog.Builder builder = new AlertDialog.Builder(this);
+                        builder.setMessage(
+                                code == 404 ? R.string.pin_expired : R.string.incorrect_pin);
+                        builder.setPositiveButton(R.string.ok, null);
+                        builder.create().show();
+                    } else {
+                        ApiDialogHelper.createError(this, code).show();
+                    }
+                });
     }
 
     @Override
@@ -312,10 +350,11 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
     @Override
     public void onVerificationRetryAt(long timestamp) {
         this.retryVerificationAfter = timestamp;
-        runOnUiThread(() -> {
-            ApiDialogHelper.createTooManyAttempts(this).show();
-            setVerifyingState(false);
-        });
+        runOnUiThread(
+                () -> {
+                    ApiDialogHelper.createTooManyAttempts(this).show();
+                    setVerifyingState(false);
+                });
         mHandler.removeCallbacks(VERIFICATION_TIMEOUT_UPDATER);
         runOnUiThread(VERIFICATION_TIMEOUT_UPDATER);
     }
@@ -326,35 +365,38 @@ public class VerifyActivity extends XmppActivity implements ClipboardManager.OnP
         setVerifyingState(true);
     }
 
-    //send sms again button callback
+    // send sms again button callback
     @Override
     public void onVerificationRequestFailed(int code) {
-        runOnUiThread(() -> {
-            setRequestingVerificationState(false);
-            ApiDialogHelper.createError(this, code).show();
-        });
+        runOnUiThread(
+                () -> {
+                    setRequestingVerificationState(false);
+                    ApiDialogHelper.createError(this, code).show();
+                });
     }
 
-    //send sms again button callback
+    // send sms again button callback
     @Override
     public void onVerificationRequested() {
-        runOnUiThread(() -> {
-            pinEntryWrapper.clear();
-            setRequestingVerificationState(false);
-            AlertDialog.Builder builder = new AlertDialog.Builder(this);
-            builder.setMessage(R.string.we_have_sent_you_another_sms);
-            builder.setPositiveButton(R.string.ok, null);
-            builder.create().show();
-        });
+        runOnUiThread(
+                () -> {
+                    pinEntryWrapper.clear();
+                    setRequestingVerificationState(false);
+                    AlertDialog.Builder builder = new AlertDialog.Builder(this);
+                    builder.setMessage(R.string.we_have_sent_you_another_sms);
+                    builder.setPositiveButton(R.string.ok, null);
+                    builder.create().show();
+                });
     }
 
     @Override
     public void onVerificationRequestedRetryAt(long timestamp) {
         this.retrySmsAfter = timestamp;
-        runOnUiThread(() -> {
-            ApiDialogHelper.createRateLimited(this, timestamp).show();
-            setRequestingVerificationState(false);
-        });
+        runOnUiThread(
+                () -> {
+                    ApiDialogHelper.createRateLimited(this, timestamp).show();
+                    setRequestingVerificationState(false);
+                });
         mHandler.removeCallbacks(SMS_TIMEOUT_UPDATER);
         runOnUiThread(SMS_TIMEOUT_UPDATER);
     }

src/quicksy/res/menu/verify_phone_number_menu.xml 🔗

@@ -0,0 +1,8 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <item
+        android:id="@+id/action_import_backup"
+        android:title="@string/restore_backup"
+        app:showAsAction="never" />
+</menu>