Backup format v2: redesign restore dialog

This commit is contained in:
Dominik Schürmann
2016-02-10 17:15:16 +01:00
parent 713f3076f4
commit a2ea509f06
3 changed files with 34 additions and 134 deletions

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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>