aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupActivity.java21
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeDisplayFragment.java126
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeEntryFragment.java212
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ToolableViewAnimator.java7
-rw-r--r--OpenKeychain/src/main/res/layout/backup_code_display_fragment.xml41
-rw-r--r--OpenKeychain/src/main/res/layout/backup_code_entry_fragment.xml302
6 files changed, 417 insertions, 292 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupActivity.java
index cc80f8910..8c1555232 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupActivity.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupActivity.java
@@ -20,7 +20,9 @@ package org.sufficientlysecure.keychain.ui;
import android.os.Bundle;
+import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
+import android.view.MenuItem;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.base.BaseActivity;
@@ -39,8 +41,10 @@ public class BackupActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
if (savedInstanceState == null) {
- BackupCodeDisplayFragment frag = BackupCodeDisplayFragment.newInstance();
+ Fragment frag = BackupCodeEntryFragment.newInstance();
FragmentManager fragMan = getSupportFragmentManager();
fragMan.beginTransaction()
@@ -50,4 +54,19 @@ public class BackupActivity extends BaseActivity {
}
}
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ FragmentManager fragMan = getSupportFragmentManager();
+ // pop from back stack, or if nothing was on there finish activity
+ if ( ! fragMan.popBackStackImmediate()) {
+ finish();
+ }
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeDisplayFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeDisplayFragment.java
deleted file mode 100644
index 89fadd8b7..000000000
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeDisplayFragment.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2015 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
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.sufficientlysecure.keychain.ui;
-
-
-import java.security.SecureRandom;
-import java.util.Random;
-
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.TextView;
-
-import org.sufficientlysecure.keychain.R;
-
-
-public class BackupCodeDisplayFragment extends Fragment {
-
- public static final String ARG_BACKUP_CODE = "backup_code";
-
- private String mBackupCode;
-
- private TextView vBackupCode;
- private Button vOkButton;
-
- public static BackupCodeDisplayFragment newInstance() {
- BackupCodeDisplayFragment frag = new BackupCodeDisplayFragment();
-
- Bundle args = new Bundle();
- args.putString(ARG_BACKUP_CODE, generateRandomCode());
- frag.setArguments(args);
-
- return frag;
- }
-
- @Override
- public void onActivityCreated(@Nullable Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.backup_code_display_fragment, container, false);
-
- vBackupCode = (TextView) view.findViewById(R.id.backup_code);
- vOkButton = (Button) view.findViewById(R.id.button_ok);
-
- return view;
- }
-
- @Override
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- if (savedInstanceState == null) {
- mBackupCode = getArguments().getString(ARG_BACKUP_CODE);
- } else {
- mBackupCode = savedInstanceState.getString(ARG_BACKUP_CODE);
- }
-
- vBackupCode.setText(mBackupCode);
-
- vOkButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- moveToCodeEntryFragment();
- }
- });
-
- }
-
- private void moveToCodeEntryFragment() {
- Fragment frag = BackupCodeEntryFragment.newInstance(mBackupCode);
- getFragmentManager().beginTransaction()
- .addToBackStack("backup_code_display")
- .replace(R.id.content_frame, frag)
- .commit();
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
-
- outState.putString(ARG_BACKUP_CODE, mBackupCode);
- }
-
- @NonNull
- private static String generateRandomCode() {
-
- Random r = new SecureRandom();
-
- // simple generation of a 20 character backup code
- StringBuilder code = new StringBuilder(28);
- for (int i = 0; i < 24; i++) {
- if (i == 6 || i == 12 || i == 18) {
- code.append('-');
- }
- code.append((char) ('A' + r.nextInt(26)));
- }
-
- return code.toString();
-
- }
-
-}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeEntryFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeEntryFragment.java
index 5dc16faba..7872fd80e 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeEntryFragment.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/BackupCodeEntryFragment.java
@@ -19,28 +19,36 @@ package org.sufficientlysecure.keychain.ui;
import java.io.File;
+import java.security.SecureRandom;
import java.text.SimpleDateFormat;
-import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
+import java.util.Random;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
+import android.graphics.Color;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.os.Handler;
import android.support.annotation.ColorInt;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentManager.OnBackStackChangedListener;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
+import android.widget.TextView;
import android.widget.ViewAnimator;
import org.sufficientlysecure.keychain.Constants;
@@ -48,24 +56,35 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.ExportHelper;
-public class BackupCodeEntryFragment extends Fragment {
+public class BackupCodeEntryFragment extends Fragment implements OnBackStackChangedListener {
public static final String ARG_BACKUP_CODE = "backup_code";
+ public static final String BACK_STACK_INPUT = "state_display";
private ExportHelper mExportHelper;
private EditText[] mCodeEditText;
- private ViewAnimator mStatusAnimator, mTitleAnimator;
+ private TextView[] mCodeDisplayText;
+ private ViewAnimator mStatusAnimator, mTitleAnimator, mCodeFieldsAnimator;
+ private int mBackStackLevel;
- public static BackupCodeEntryFragment newInstance(String backupCode) {
+ public static BackupCodeEntryFragment newInstance() {
BackupCodeEntryFragment frag = new BackupCodeEntryFragment();
Bundle args = new Bundle();
- args.putString(ARG_BACKUP_CODE, backupCode);
+ args.putString(ARG_BACKUP_CODE, generateRandomCode());
frag.setArguments(args);
return frag;
}
+ enum BackupCodeState {
+ STATE_UNINITIALIZED, STATE_DISPLAY, STATE_INPUT, STATE_INPUT_ERROR, STATE_OK
+ }
+
+ StringBuilder mCurrentCodeInput = new StringBuilder("---------------------------");
+ BackupCodeState mCurrentState = BackupCodeState.STATE_UNINITIALIZED;
+ String mBackupCode;
+
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
@@ -79,7 +98,65 @@ public class BackupCodeEntryFragment extends Fragment {
mExportHelper = null;
}
- String mBackupCode;
+ void switchState(BackupCodeState state) {
+
+ switch (state) {
+ case STATE_DISPLAY:
+ mTitleAnimator.setDisplayedChild(0);
+ mStatusAnimator.setDisplayedChild(0);
+ mCodeFieldsAnimator.setDisplayedChild(0);
+
+ break;
+
+ case STATE_INPUT:
+ mTitleAnimator.setDisplayedChild(1);
+ mStatusAnimator.setDisplayedChild(1);
+ mCodeFieldsAnimator.setDisplayedChild(1);
+
+ for (EditText editText : mCodeEditText) {
+ editText.setText("");
+ }
+
+ pushOntoBackStack();
+
+ break;
+
+ case STATE_INPUT_ERROR: {
+ mStatusAnimator.setDisplayedChild(2);
+
+ // we know all fields are filled, so if it's not the *right* one it's a *wrong* one!
+ @ColorInt int black = mCodeEditText[0].getCurrentTextColor();
+ @ColorInt int red = getResources().getColor(R.color.android_red_dark);
+ for (EditText editText : mCodeEditText) {
+ animateFlashText(editText, black, red, false);
+ }
+
+ break;
+ }
+
+ case STATE_OK: {
+ mTitleAnimator.setDisplayedChild(2);
+ mStatusAnimator.setDisplayedChild(3);
+
+ hideKeyboard();
+
+ @ColorInt int black = mCodeEditText[0].getCurrentTextColor();
+ @ColorInt int green = getResources().getColor(R.color.android_green_dark);
+ for (EditText editText : mCodeEditText) {
+ editText.setEnabled(false);
+ animateFlashText(editText, black, green, true);
+ }
+
+ popFromBackStackNoAction();
+
+ break;
+ }
+
+ }
+
+ mCurrentState = state;
+
+ }
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
@@ -93,16 +170,45 @@ public class BackupCodeEntryFragment extends Fragment {
mCodeEditText[2] = (EditText) view.findViewById(R.id.backup_code_3);
mCodeEditText[3] = (EditText) view.findViewById(R.id.backup_code_4);
+ mCodeDisplayText = new TextView[4];
+ mCodeDisplayText[0] = (TextView) view.findViewById(R.id.backup_code_display_1);
+ mCodeDisplayText[1] = (TextView) view.findViewById(R.id.backup_code_display_2);
+ mCodeDisplayText[2] = (TextView) view.findViewById(R.id.backup_code_display_3);
+ mCodeDisplayText[3] = (TextView) view.findViewById(R.id.backup_code_display_4);
+
+ { // set backup code in code TextViews
+ char[] backupCode = mBackupCode.toCharArray();
+ for (int i = 0; i < mCodeDisplayText.length; i++) {
+ mCodeDisplayText[i].setText(backupCode, i * 7, 6);
+ }
+ }
+
+ { // set background to null in TextViews - this will retain padding from EditText style!
+ for (TextView textView : mCodeDisplayText) {
+ // noinspection deprecation, setBackground(Drawable) is API level >=16
+ textView.setBackgroundDrawable(null);
+ }
+ }
+
setupEditTextFocusNext(mCodeEditText);
setupEditTextSuccessListener(mCodeEditText);
mStatusAnimator = (ViewAnimator) view.findViewById(R.id.status_animator);
mTitleAnimator = (ViewAnimator) view.findViewById(R.id.title_animator);
+ mCodeFieldsAnimator = (ViewAnimator) view.findViewById(R.id.code_animator);
+
+ View backupInput = view.findViewById(R.id.button_backup_input);
+ backupInput.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ switchState(BackupCodeState.STATE_INPUT);
+ }
+ });
View backupSave = view.findViewById(R.id.button_backup_save);
View backupShare = view.findViewById(R.id.button_backup_share);
- backupSave.setOnClickListener(new View.OnClickListener() {
+ backupSave.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startBackup(true);
@@ -112,7 +218,14 @@ public class BackupCodeEntryFragment extends Fragment {
return view;
}
- StringBuilder mCurrentCodeInput = new StringBuilder("---------------------------");
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ if (mCurrentState == BackupCodeState.STATE_UNINITIALIZED) {
+ switchState(BackupCodeState.STATE_DISPLAY);
+ }
+ }
private void setupEditTextSuccessListener(final EditText[] backupCodes) {
for (int i = 0; i < backupCodes.length; i++) {
@@ -133,6 +246,13 @@ public class BackupCodeEntryFragment extends Fragment {
if (s.length() > 6) {
throw new AssertionError("max length of each field is 6!");
}
+
+ boolean inInputState = mCurrentState == BackupCodeState.STATE_INPUT
+ || mCurrentState == BackupCodeState.STATE_INPUT_ERROR;
+ if (!inInputState) {
+ return;
+ }
+
// we could do this in better granularity in onTextChanged, but it's not worth it
mCurrentCodeInput.replace(index, index +s.length(), s.toString());
// if (s.length() == 6) {
@@ -154,43 +274,16 @@ public class BackupCodeEntryFragment extends Fragment {
// if they don't match, do nothing
if (mCurrentCodeInput.toString().equals(mBackupCode)) {
- codeInputSuccessful();
+ switchState(BackupCodeState.STATE_OK);
return;
}
if (mCurrentCodeInput.toString().startsWith("ABC")) {
- codeInputSuccessful();
+ switchState(BackupCodeState.STATE_OK);
return;
}
- // we know all fields are filled, so if it's not the *right* one it's a *wrong* one!
- @ColorInt int black = mCodeEditText[0].getCurrentTextColor();
- @ColorInt int red = getResources().getColor(R.color.android_red_dark);
- for (EditText editText : mCodeEditText) {
- animateFlashText(editText, black, red, false);
- }
- mStatusAnimator.setDisplayedChild(1);
-
- }
-
- boolean mSuccessful = false;
- private void codeInputSuccessful() {
- if (mSuccessful) {
- return;
- }
- mSuccessful = true;
-
- hideKeyboard();
-
- mTitleAnimator.setDisplayedChild(1);
- mStatusAnimator.setDisplayedChild(2);
-
- @ColorInt int black = mCodeEditText[0].getCurrentTextColor();
- @ColorInt int green = getResources().getColor(R.color.android_green_dark);
- for (EditText editText : mCodeEditText) {
- animateFlashText(editText, black, green, true);
- editText.setEnabled(false);
- }
+ switchState(BackupCodeState.STATE_INPUT_ERROR);
}
@@ -239,6 +332,28 @@ public class BackupCodeEntryFragment extends Fragment {
}
}
+ private void pushOntoBackStack() {
+ FragmentManager fragMan = getFragmentManager();
+ mBackStackLevel = fragMan.getBackStackEntryCount();
+ fragMan.beginTransaction().addToBackStack(BACK_STACK_INPUT).commit();
+ fragMan.addOnBackStackChangedListener(this);
+ }
+
+ private void popFromBackStackNoAction() {
+ FragmentManager fragMan = getFragmentManager();
+ fragMan.removeOnBackStackChangedListener(this);
+ fragMan.popBackStack(BACK_STACK_INPUT, FragmentManager.POP_BACK_STACK_INCLUSIVE);
+ }
+
+ @Override
+ public void onBackStackChanged() {
+ FragmentManager fragMan = getFragmentManager();
+ if (fragMan.getBackStackEntryCount() == mBackStackLevel) {
+ fragMan.removeOnBackStackChangedListener(this);
+ switchState(BackupCodeState.STATE_DISPLAY);
+ }
+ }
+
private void startBackup(boolean exportSecret) {
File filename;
String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
@@ -266,4 +381,23 @@ public class BackupCodeEntryFragment extends Fragment {
inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
+ @NonNull
+ private static String generateRandomCode() {
+
+ Random r = new SecureRandom();
+
+ // simple generation of a 20 character backup code
+ StringBuilder code = new StringBuilder(28);
+ for (int i = 0; i < 24; i++) {
+ if (i == 6 || i == 12 || i == 18) {
+ code.append('-');
+ }
+ code.append((char) ('A' + r.nextInt(26)));
+ }
+
+ return code.toString();
+
+ }
+
+
}
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ToolableViewAnimator.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ToolableViewAnimator.java
index 18e830139..bd611e6bb 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ToolableViewAnimator.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/ToolableViewAnimator.java
@@ -73,4 +73,11 @@ public class ToolableViewAnimator extends ViewAnimator {
}
super.addView(child, index, params);
}
+
+ @Override
+ public void setDisplayedChild(int whichChild) {
+ if (whichChild != getDisplayedChild()) {
+ super.setDisplayedChild(whichChild);
+ }
+ }
}
diff --git a/OpenKeychain/src/main/res/layout/backup_code_display_fragment.xml b/OpenKeychain/src/main/res/layout/backup_code_display_fragment.xml
deleted file mode 100644
index b7fc5150b..000000000
--- a/OpenKeychain/src/main/res/layout/backup_code_display_fragment.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingTop="50dp">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="10dp"
- android:layout_gravity="center_horizontal"
- android:gravity="center_horizontal"
- android:text="Your key backup will be secured with this backup code:"
- style="?android:textAppearanceMedium"
- />
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="20dp"
- android:layout_marginBottom="20dp"
- android:id="@+id/backup_code"
- tools:text="ABCDEF-FGHIJK-KLMNOP-PQRSTU"
- android:textStyle="bold"
- android:typeface="monospace"
- android:textSize="@dimen/abc_text_size_medium_material" />
-
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_margin="10dp"
- android:text="Ok, I wrote it down!"
- android:id="@+id/button_ok"
- style="?buttonStyle"
- />
-
-</LinearLayout>
diff --git a/OpenKeychain/src/main/res/layout/backup_code_entry_fragment.xml b/OpenKeychain/src/main/res/layout/backup_code_entry_fragment.xml
index d6ee84761..b4938d5e9 100644
--- a/OpenKeychain/src/main/res/layout/backup_code_entry_fragment.xml
+++ b/OpenKeychain/src/main/res/layout/backup_code_entry_fragment.xml
@@ -7,7 +7,6 @@
android:layout_height="match_parent"
android:paddingTop="50dp">
-
<org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator
android:layout_height="wrap_content"
android:layout_width="match_parent"
@@ -15,7 +14,17 @@
android:id="@+id/title_animator"
android:inAnimation="@anim/fade_in"
android:outAnimation="@anim/fade_out"
- custom:initialView="1">
+ custom:initialView="0">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="10dp"
+ android:layout_gravity="center_horizontal"
+ android:gravity="center_horizontal"
+ android:text="The backup will be secured with a backup code. Write it down before you proceed!"
+ style="?android:textAppearanceMedium"
+ />
<TextView
android:layout_width="wrap_content"
@@ -39,100 +48,210 @@
</org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator>
- <LinearLayout
- android:layout_width="wrap_content"
+ <org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator
android:layout_height="wrap_content"
+ android:layout_width="match_parent"
android:layout_gravity="center_horizontal"
- android:layout_marginTop="20dp"
- android:layout_marginBottom="20dp"
- >
+ android:id="@+id/code_animator"
+ android:inAnimation="@anim/fade_in"
+ android:outAnimation="@anim/fade_out"
+ android:layout_marginTop="15dp"
+ android:layout_marginBottom="15dp"
+ custom:initialView="0">
- <EditText
+ <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- android:id="@+id/backup_code_1"
- android:textStyle="bold"
- android:typeface="monospace"
- android:textSize="@dimen/abc_text_size_medium_material"
- android:hint="ABCDEF"
- android:singleLine="true"
- android:inputType="textNoSuggestions|textCapCharacters"
- android:maxLength="6"
- />
+ >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center_vertical"
- android:textStyle="bold"
- android:typeface="monospace"
- android:textSize="@dimen/abc_text_size_medium_material"
- android:text="-"
- />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:id="@+id/backup_code_display_1"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ style="@android:style/Widget.EditText"
+ android:clickable="false"
+ android:focusable="false"
+ tools:text="ABCDEF"
+ />
- <EditText
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:id="@+id/backup_code_2"
- android:textStyle="bold"
- android:typeface="monospace"
- android:textSize="@dimen/abc_text_size_medium_material"
- android:hint="GHIJKL"
- android:singleLine="true"
- android:inputType="textNoSuggestions|textCapCharacters"
- android:maxLength="6"
- />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ android:text="-"
+ />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center_vertical"
- android:textStyle="bold"
- android:typeface="monospace"
- android:textSize="@dimen/abc_text_size_medium_material"
- android:text="-"
- />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:id="@+id/backup_code_display_2"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ style="@android:style/Widget.EditText"
+ android:clickable="false"
+ android:focusable="false"
+ tools:text="GHIJKL"
+ />
- <EditText
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:id="@+id/backup_code_3"
- android:textStyle="bold"
- android:typeface="monospace"
- android:textSize="@dimen/abc_text_size_medium_material"
- android:hint="MNOPQR"
- android:singleLine="true"
- android:inputType="textNoSuggestions|textCapCharacters"
- android:maxLength="6"
- />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center_vertical"
- android:textStyle="bold"
- android:typeface="monospace"
- android:textSize="@dimen/abc_text_size_medium_material"
- android:text="-"
- />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ android:text="-"
+ />
- <EditText
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:id="@+id/backup_code_display_3"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ style="@android:style/Widget.EditText"
+ android:clickable="false"
+ android:focusable="false"
+ tools:text="MNOPQR"
+ />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ android:text="-"
+ />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:id="@+id/backup_code_display_4"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ android:singleLine="true"
+ style="@android:style/Widget.EditText"
+ android:clickable="false"
+ android:focusable="false"
+ tools:text="STUVWX"
+ />
+
+ </LinearLayout>
+
+ <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- android:id="@+id/backup_code_4"
- android:textStyle="bold"
- android:typeface="monospace"
- android:textSize="@dimen/abc_text_size_medium_material"
- android:hint="STUVWX"
- android:singleLine="true"
- android:inputType="textNoSuggestions|textCapCharacters"
- android:maxLength="6"
- />
+ >
+
+ <EditText
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:id="@+id/backup_code_1"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions|textCapCharacters"
+ android:hint="ABCDEF"
+ android:textColorHint="@android:color/transparent"
+ android:maxLength="6"
+ />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ android:text="-"
+ />
+
+ <EditText
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:id="@+id/backup_code_2"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions|textCapCharacters"
+ android:hint="ABCDEF"
+ android:textColorHint="@android:color/transparent"
+ android:maxLength="6"
+ />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ android:text="-"
+ />
+
+ <EditText
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:id="@+id/backup_code_3"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions|textCapCharacters"
+ android:hint="ABCDEF"
+ android:textColorHint="@android:color/transparent"
+ android:maxLength="6"
+ />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:gravity="center_vertical"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ android:text="-"
+ />
- </LinearLayout>
+ <EditText
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:id="@+id/backup_code_4"
+ android:textStyle="bold"
+ android:typeface="monospace"
+ android:textSize="@dimen/abc_text_size_medium_material"
+ android:singleLine="true"
+ android:inputType="textNoSuggestions|textCapCharacters"
+ android:hint="ABCDEF"
+ android:textColorHint="@android:color/transparent"
+ android:maxLength="6"
+ />
+
+ </LinearLayout>
+
+ </org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator>
<org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator
android:layout_height="wrap_content"
@@ -140,8 +259,21 @@
android:layout_gravity="center_horizontal"
android:id="@+id/status_animator"
android:inAnimation="@anim/fade_in_delayed"
- android:outAnimation="@anim/fade_out_delayed"
- custom:initialView="2">
+ android:outAnimation="@anim/fade_out"
+ custom:initialView="0">
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_margin="10dp"
+ android:text="Ok, I wrote it down!"
+ android:drawableLeft="@drawable/ic_check_white_24dp"
+ android:drawablePadding="8dp"
+ android:padding="12dp"
+ android:id="@+id/button_backup_input"
+ style="?android:buttonBarButtonStyle"
+ />
<Space
android:layout_width="wrap_content"
@@ -170,7 +302,7 @@
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="12dp"
- android:text="Share backup…"
+ android:text="Share backup"
android:drawableLeft="@drawable/ic_share_grey_24dp"
android:drawablePadding="8dp"
android:id="@+id/button_backup_share"
@@ -182,7 +314,7 @@
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="12dp"
- android:text="Save backup…"
+ android:text="Save backup"
android:drawableLeft="@drawable/ic_save_grey_24dp"
android:drawablePadding="8dp"
android:id="@+id/button_backup_save"