Backup format v2: redesign restore dialog
This commit is contained in:
@@ -278,7 +278,7 @@ public class PgpDecryptVerifyOperation extends BaseOperation<PgpDecryptVerifyInp
|
||||
ArmorHeaders armorHeaders = parseArmorHeaders(in, log, indent);
|
||||
String charset = armorHeaders.charset;
|
||||
boolean useBackupCode = false;
|
||||
if (armorHeaders.backupVersion != null && armorHeaders.backupVersion == 1) {
|
||||
if (armorHeaders.backupVersion != null && armorHeaders.backupVersion == 2) {
|
||||
useBackupCode = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
* Copyright (C) 2014-2016 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -46,6 +46,8 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.ViewAnimator;
|
||||
|
||||
import com.github.pinball83.maskededittext.MaskedEditText;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey;
|
||||
@@ -158,7 +160,7 @@ public class PassphraseDialogActivity extends FragmentActivity {
|
||||
public static class PassphraseDialogFragment extends DialogFragment implements TextView.OnEditorActionListener {
|
||||
private EditText mPassphraseEditText;
|
||||
private TextView mPassphraseText;
|
||||
private EditText[] mBackupCodeEditText;
|
||||
private MaskedEditText mBackupCodeEditText;
|
||||
|
||||
private boolean mIsCancelled = false;
|
||||
private RequiredInputParcel mRequiredInput;
|
||||
@@ -185,12 +187,13 @@ public class PassphraseDialogActivity extends FragmentActivity {
|
||||
View view = inflater.inflate(R.layout.passphrase_dialog_backup_code, null);
|
||||
alert.setView(view);
|
||||
|
||||
mBackupCodeEditText = new EditText[4];
|
||||
mBackupCodeEditText[0] = (EditText) view.findViewById(R.id.backup_code_1);
|
||||
mBackupCodeEditText[1] = (EditText) view.findViewById(R.id.backup_code_2);
|
||||
mBackupCodeEditText[2] = (EditText) view.findViewById(R.id.backup_code_3);
|
||||
mBackupCodeEditText[3] = (EditText) view.findViewById(R.id.backup_code_4);
|
||||
setupEditTextFocusNext(mBackupCodeEditText);
|
||||
mBackupCodeEditText = (MaskedEditText) view.findViewById(R.id.backup_code);
|
||||
// NOTE: order of these method calls matter, see setupAutomaticLinebreak()
|
||||
mBackupCodeEditText.setInputType(
|
||||
InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
|
||||
setupAutomaticLinebreak(mBackupCodeEditText);
|
||||
mBackupCodeEditText.setImeActionLabel(getString(android.R.string.ok), EditorInfo.IME_ACTION_DONE);
|
||||
mBackupCodeEditText.setOnEditorActionListener(this);
|
||||
|
||||
AlertDialog dialog = alert.create();
|
||||
dialog.setButton(DialogInterface.BUTTON_POSITIVE,
|
||||
@@ -324,32 +327,16 @@ public class PassphraseDialogActivity extends FragmentActivity {
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private static void setupEditTextFocusNext(final EditText[] backupCodes) {
|
||||
for (int i = 0; i < backupCodes.length - 1; i++) {
|
||||
|
||||
final int next = i + 1;
|
||||
|
||||
backupCodes[i].addTextChangedListener(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) {
|
||||
boolean inserting = before < count;
|
||||
boolean cursorAtEnd = (start + count) == 6;
|
||||
|
||||
if (inserting && cursorAtEnd) {
|
||||
backupCodes[next].requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
/**
|
||||
* Automatic line break with max 6 lines for smaller displays
|
||||
* <p/>
|
||||
* NOTE: I was not able to get this behaviour using XML!
|
||||
* Looks like the order of these method calls matter, see http://stackoverflow.com/a/11171307
|
||||
*/
|
||||
private void setupAutomaticLinebreak(TextView textview) {
|
||||
textview.setSingleLine(true);
|
||||
textview.setMaxLines(6);
|
||||
textview.setHorizontallyScrolling(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -363,17 +350,8 @@ public class PassphraseDialogActivity extends FragmentActivity {
|
||||
public void onClick(View v) {
|
||||
|
||||
if (mRequiredInput.mType == RequiredInputType.BACKUP_CODE) {
|
||||
StringBuilder backupCodeInput = new StringBuilder(26);
|
||||
for (EditText editText : mBackupCodeEditText) {
|
||||
if (editText.getText().length() < 6) {
|
||||
return;
|
||||
}
|
||||
backupCodeInput.append(editText.getText());
|
||||
backupCodeInput.append('-');
|
||||
}
|
||||
backupCodeInput.deleteCharAt(backupCodeInput.length() - 1);
|
||||
|
||||
Passphrase passphrase = new Passphrase(backupCodeInput.toString());
|
||||
Passphrase passphrase =
|
||||
new Passphrase(mBackupCodeEditText.getText().toString());
|
||||
finishCaching(passphrase);
|
||||
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -27,99 +28,20 @@
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<!--
|
||||
The most reliable way to correctly size these I found was to put a transparent hint on them.
|
||||
Theoretically, this should be what the android:ems attribute is for - didn't work for me.
|
||||
-->
|
||||
<EditText
|
||||
android:id="@+id/backup_code_1"
|
||||
<com.github.pinball83.maskededittext.MaskedEditText
|
||||
android:id="@+id/backup_code"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:hint="ABCDEF"
|
||||
android:inputType="textNoSuggestions|textCapCharacters"
|
||||
android:maxLength="6"
|
||||
android:singleLine="true"
|
||||
android:textColorHint="@android:color/transparent"
|
||||
android:textSize="14dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:textSize="18dp"
|
||||
android:textStyle="bold"
|
||||
android:typeface="monospace"
|
||||
tools:ignore="HardcodedText,SpUsage" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:text="-"
|
||||
android:textSize="14dp"
|
||||
android:textStyle="bold"
|
||||
android:typeface="monospace"
|
||||
tools:ignore="HardcodedText,SpUsage" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/backup_code_2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:hint="ABCDEF"
|
||||
android:inputType="textNoSuggestions|textCapCharacters"
|
||||
android:maxLength="6"
|
||||
android:singleLine="true"
|
||||
android:textColorHint="@android:color/transparent"
|
||||
android:textSize="14dp"
|
||||
android:textStyle="bold"
|
||||
android:typeface="monospace"
|
||||
tools:ignore="HardcodedText,SpUsage" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:text="-"
|
||||
android:textSize="14dp"
|
||||
android:textStyle="bold"
|
||||
android:typeface="monospace"
|
||||
tools:ignore="HardcodedText,SpUsage" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/backup_code_3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:hint="ABCDEF"
|
||||
android:inputType="textNoSuggestions|textCapCharacters"
|
||||
android:maxLength="6"
|
||||
android:singleLine="true"
|
||||
android:textColorHint="@android:color/transparent"
|
||||
android:textSize="14dp"
|
||||
android:textStyle="bold"
|
||||
android:typeface="monospace"
|
||||
tools:ignore="HardcodedText,SpUsage" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:text="-"
|
||||
android:textSize="14dp"
|
||||
android:textStyle="bold"
|
||||
android:typeface="monospace"
|
||||
tools:ignore="HardcodedText,SpUsage" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/backup_code_4"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:hint="ABCDEF"
|
||||
android:inputType="textNoSuggestions|textCapCharacters"
|
||||
android:maxLength="6"
|
||||
android:singleLine="true"
|
||||
android:textColorHint="@android:color/transparent"
|
||||
android:textSize="14dp"
|
||||
android:textStyle="bold"
|
||||
android:typeface="monospace"
|
||||
tools:ignore="HardcodedText,SpUsage" />
|
||||
app:mask="****-****-****-****-****-****"
|
||||
app:maskIconColor="@color/colorPrimary"
|
||||
app:notMaskedSymbol="*"
|
||||
tools:ignore="SpUsage" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
Reference in New Issue
Block a user