Move error overlay into generalized DecryptFragment, better error handling in DecryptTextActivity

This commit is contained in:
Dominik Schürmann 2015-05-06 03:26:42 +02:00
parent 9c0187c6b4
commit f102ae5da5
5 changed files with 186 additions and 122 deletions

View File

@ -31,6 +31,7 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
@ -232,7 +233,6 @@ public class DecryptFilesFragment extends DecryptFragment {
returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT);
if (pgpResult.success()) { if (pgpResult.success()) {
switch (mCurrentCryptoOperation) { switch (mCurrentCryptoOperation) {
case KeychainIntentService.ACTION_DECRYPT_METADATA: { case KeychainIntentService.ACTION_DECRYPT_METADATA: {
askForOutputFilename(pgpResult.getDecryptMetadata().getFilename()); askForOutputFilename(pgpResult.getDecryptMetadata().getFilename());
@ -264,9 +264,8 @@ public class DecryptFilesFragment extends DecryptFragment {
break; break;
} }
} }
} else {
pgpResult.createNotify(getActivity()).show();
} }
pgpResult.createNotify(getActivity()).show(DecryptFilesFragment.this);
} }
} }

View File

@ -30,6 +30,7 @@ import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader; import android.support.v4.content.Loader;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
@ -61,17 +62,18 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
public static final int LOADER_ID_UNIFIED = 0; public static final int LOADER_ID_UNIFIED = 0;
protected LinearLayout mResultLayout; protected LinearLayout mResultLayout;
protected ImageView mEncryptionIcon; protected ImageView mEncryptionIcon;
protected TextView mEncryptionText; protected TextView mEncryptionText;
protected ImageView mSignatureIcon; protected ImageView mSignatureIcon;
protected TextView mSignatureText; protected TextView mSignatureText;
protected View mSignatureLayout; protected View mSignatureLayout;
protected TextView mSignatureName; protected TextView mSignatureName;
protected TextView mSignatureEmail; protected TextView mSignatureEmail;
protected TextView mSignatureAction; protected TextView mSignatureAction;
private LinearLayout mContentLayout;
private LinearLayout mErrorOverlayLayout;
private OpenPgpSignatureResult mSignatureResult; private OpenPgpSignatureResult mSignatureResult;
@Override @Override
@ -81,7 +83,6 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
// NOTE: These views are inside the activity! // NOTE: These views are inside the activity!
mResultLayout = (LinearLayout) getActivity().findViewById(R.id.result_main_layout); mResultLayout = (LinearLayout) getActivity().findViewById(R.id.result_main_layout);
mResultLayout.setVisibility(View.GONE); mResultLayout.setVisibility(View.GONE);
mEncryptionIcon = (ImageView) getActivity().findViewById(R.id.result_encryption_icon); mEncryptionIcon = (ImageView) getActivity().findViewById(R.id.result_encryption_icon);
mEncryptionText = (TextView) getActivity().findViewById(R.id.result_encryption_text); mEncryptionText = (TextView) getActivity().findViewById(R.id.result_encryption_text);
mSignatureIcon = (ImageView) getActivity().findViewById(R.id.result_signature_icon); mSignatureIcon = (ImageView) getActivity().findViewById(R.id.result_signature_icon);
@ -90,6 +91,18 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
mSignatureName = (TextView) getActivity().findViewById(R.id.result_signature_name); mSignatureName = (TextView) getActivity().findViewById(R.id.result_signature_name);
mSignatureEmail = (TextView) getActivity().findViewById(R.id.result_signature_email); mSignatureEmail = (TextView) getActivity().findViewById(R.id.result_signature_email);
mSignatureAction = (TextView) getActivity().findViewById(R.id.result_signature_action); mSignatureAction = (TextView) getActivity().findViewById(R.id.result_signature_action);
// Overlay
mContentLayout = (LinearLayout) view.findViewById(R.id.decrypt_content);
mErrorOverlayLayout = (LinearLayout) view.findViewById(R.id.decrypt_error_overlay);
Button vErrorOverlayButton = (Button) view.findViewById(R.id.decrypt_error_overlay_button);
vErrorOverlayButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
}
});
} }
private void lookupUnknownKey(long unknownKeyId) { private void lookupUnknownKey(long unknownKeyId) {
@ -185,6 +198,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
getLoaderManager().destroyLoader(LOADER_ID_UNIFIED); getLoaderManager().destroyLoader(LOADER_ID_UNIFIED);
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
onVerifyLoaded(true); onVerifyLoaded(true);
return; return;
@ -285,6 +301,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
setSignatureLayoutVisibility(View.VISIBLE); setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(signatureKeyId); setShowAction(signatureKeyId);
mErrorOverlayLayout.setVisibility(View.VISIBLE);
mContentLayout.setVisibility(View.GONE);
onVerifyLoaded(false); onVerifyLoaded(false);
} else if (isExpired) { } else if (isExpired) {
@ -294,6 +313,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
setSignatureLayoutVisibility(View.VISIBLE); setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(signatureKeyId); setShowAction(signatureKeyId);
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
onVerifyLoaded(true); onVerifyLoaded(true);
} else if (isYours) { } else if (isYours) {
@ -304,6 +326,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
setSignatureLayoutVisibility(View.VISIBLE); setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(signatureKeyId); setShowAction(signatureKeyId);
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
onVerifyLoaded(true); onVerifyLoaded(true);
} else if (isVerified) { } else if (isVerified) {
@ -313,6 +338,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
setSignatureLayoutVisibility(View.VISIBLE); setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(signatureKeyId); setShowAction(signatureKeyId);
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
onVerifyLoaded(true); onVerifyLoaded(true);
} else { } else {
@ -322,6 +350,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
setSignatureLayoutVisibility(View.VISIBLE); setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(signatureKeyId); setShowAction(signatureKeyId);
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
onVerifyLoaded(true); onVerifyLoaded(true);
} }
@ -378,6 +409,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
} }
}); });
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
onVerifyLoaded(true); onVerifyLoaded(true);
break; break;
@ -389,6 +423,9 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements
setSignatureLayoutVisibility(View.GONE); setSignatureLayoutVisibility(View.GONE);
mErrorOverlayLayout.setVisibility(View.VISIBLE);
mContentLayout.setVisibility(View.GONE);
onVerifyLoaded(false); onVerifyLoaded(false);
break; break;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de> * Copyright (C) 2012-2015 Dominik Schürmann <dominik@dominikschuermann.de>
* Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org> * Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -23,16 +23,16 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.widget.Toast;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection; import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.SingletonResult; import org.sufficientlysecure.keychain.operations.results.SingletonResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper; import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.ui.base.BaseActivity; import org.sufficientlysecure.keychain.ui.base.BaseActivity;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Log;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -138,8 +138,6 @@ public class DecryptTextActivity extends BaseActivity {
/** /**
* Handles all actions with this intent * Handles all actions with this intent
*
* @param intent
*/ */
private void handleActions(Bundle savedInstanceState, Intent intent) { private void handleActions(Bundle savedInstanceState, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
@ -162,10 +160,14 @@ public class DecryptTextActivity extends BaseActivity {
if (sharedText != null) { if (sharedText != null) {
loadFragment(savedInstanceState, sharedText); loadFragment(savedInstanceState, sharedText);
} else { } else {
Notify.create(this, R.string.error_invalid_data, Notify.Style.ERROR).show(); Log.e(Constants.TAG, "EXTRA_TEXT does not contain PGP content!");
Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show();
finish();
} }
} else { } else {
Log.e(Constants.TAG, "ACTION_SEND received non-plaintext, this should not happen in this activity!"); Log.e(Constants.TAG, "ACTION_SEND received non-plaintext, this should not happen in this activity!");
Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show();
finish();
} }
} else if (ACTION_DECRYPT_TEXT.equals(action)) { } else if (ACTION_DECRYPT_TEXT.equals(action)) {
Log.d(Constants.TAG, "ACTION_DECRYPT_TEXT"); Log.d(Constants.TAG, "ACTION_DECRYPT_TEXT");
@ -176,7 +178,9 @@ public class DecryptTextActivity extends BaseActivity {
if (extraText != null) { if (extraText != null) {
loadFragment(savedInstanceState, extraText); loadFragment(savedInstanceState, extraText);
} else { } else {
Notify.create(this, R.string.error_invalid_data, Notify.Style.ERROR).show(); Log.e(Constants.TAG, "EXTRA_TEXT does not contain PGP content!");
Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show();
finish();
} }
} else if (ACTION_DECRYPT_FROM_CLIPBOARD.equals(action)) { } else if (ACTION_DECRYPT_FROM_CLIPBOARD.equals(action)) {
Log.d(Constants.TAG, "ACTION_DECRYPT_FROM_CLIPBOARD"); Log.d(Constants.TAG, "ACTION_DECRYPT_FROM_CLIPBOARD");
@ -191,6 +195,7 @@ public class DecryptTextActivity extends BaseActivity {
} }
} else if (ACTION_DECRYPT_TEXT.equals(action)) { } else if (ACTION_DECRYPT_TEXT.equals(action)) {
Log.e(Constants.TAG, "Include the extra 'text' in your Intent!"); Log.e(Constants.TAG, "Include the extra 'text' in your Intent!");
Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show();
finish(); finish();
} }
} }

View File

@ -50,8 +50,6 @@ public class DecryptTextFragment extends DecryptFragment {
public static final String ARG_CIPHERTEXT = "ciphertext"; public static final String ARG_CIPHERTEXT = "ciphertext";
// view // view
private LinearLayout mContentLayout;
private LinearLayout mErrorOverlayLayout;
private TextView mText; private TextView mText;
// model // model
@ -78,19 +76,8 @@ public class DecryptTextFragment extends DecryptFragment {
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false); View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false);
mContentLayout = (LinearLayout) view.findViewById(R.id.decrypt_content);
mErrorOverlayLayout = (LinearLayout) view.findViewById(R.id.decrypt_error_overlay);
mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext); mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext);
Button vErrorOverlayButton = (Button) view.findViewById(R.id.decrypt_error_overlay_button);
vErrorOverlayButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
}
});
return view; return view;
} }
@ -203,7 +190,6 @@ public class DecryptTextFragment extends DecryptFragment {
returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT); returnData.getParcelable(DecryptVerifyResult.EXTRA_RESULT);
if (pgpResult.success()) { if (pgpResult.success()) {
byte[] decryptedMessage = returnData byte[] decryptedMessage = returnData
.getByteArray(KeychainIntentService.RESULT_DECRYPTED_BYTES); .getByteArray(KeychainIntentService.RESULT_DECRYPTED_BYTES);
String displayMessage; String displayMessage;
@ -219,15 +205,12 @@ public class DecryptTextFragment extends DecryptFragment {
} }
mText.setText(displayMessage); mText.setText(displayMessage);
pgpResult.createNotify(getActivity()).show();
// display signature result in activity // display signature result in activity
loadVerifyResult(pgpResult); loadVerifyResult(pgpResult);
} else { } else {
pgpResult.createNotify(getActivity()).show();
// TODO: show also invalid layout with different text? // TODO: show also invalid layout with different text?
} }
pgpResult.createNotify(getActivity()).show(DecryptTextFragment.this);
} }
} }
}; };
@ -245,17 +228,7 @@ public class DecryptTextFragment extends DecryptFragment {
@Override @Override
protected void onVerifyLoaded(boolean hideErrorOverlay) { protected void onVerifyLoaded(boolean hideErrorOverlay) {
mShowMenuOptions = hideErrorOverlay; mShowMenuOptions = hideErrorOverlay;
getActivity().supportInvalidateOptionsMenu(); getActivity().supportInvalidateOptionsMenu();
if (hideErrorOverlay) {
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
} else {
mErrorOverlayLayout.setVisibility(View.VISIBLE);
mContentLayout.setVisibility(View.GONE);
}
} }
} }

View File

@ -1,99 +1,149 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fillViewport="true"> android:orientation="vertical">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<View <ScrollView
android:id="@+id/status_divider" android:fillViewport="true"
android:layout_height="1dip" android:paddingTop="8dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:background="?android:attr/listDivider" /> android:scrollbars="vertical"
android:layout_height="0dp"
<LinearLayout android:layout_weight="1">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="4dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="vertical">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:id="@+id/decrypt_file_browse"
android:clickable="true"
android:background="?android:selectableItemBackground">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/label_file_colon"
android:gravity="center_vertical" />
<TextView
android:id="@+id/decrypt_file_filename"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/filemanager_title_open"
android:drawableRight="@drawable/ic_folder_grey_24dp"
android:drawablePadding="8dp"
android:gravity="center_vertical" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="?android:attr/listDivider"
android:layout_marginBottom="8dp" />
<CheckBox
android:id="@+id/decrypt_file_delete_after_decryption"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/label_delete_after_decryption" /> android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/decrypt_file_action_decrypt"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:text="@string/btn_decrypt_verify_file"
android:clickable="true"
android:background="?android:selectableItemBackground"
android:drawableRight="@drawable/ic_save_grey_24dp"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<View <View
android:layout_width="match_parent" android:id="@+id/status_divider"
android:layout_height="1dip" android:layout_height="1dip"
android:background="?android:attr/listDivider" android:layout_width="match_parent"
android:layout_above="@+id/decrypt_file_action_decrypt" /> android:background="?android:attr/listDivider" />
</RelativeLayout> <LinearLayout
</LinearLayout> android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="4dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:id="@+id/decrypt_file_browse"
android:clickable="true"
android:background="?android:selectableItemBackground">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/label_file_colon"
android:gravity="center_vertical" />
<TextView
android:id="@+id/decrypt_file_filename"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/filemanager_title_open"
android:drawableRight="@drawable/ic_folder_grey_24dp"
android:drawablePadding="8dp"
android:gravity="center_vertical" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="?android:attr/listDivider"
android:layout_marginBottom="8dp" />
<CheckBox
android:id="@+id/decrypt_file_delete_after_decryption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_delete_after_decryption" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/decrypt_file_action_decrypt"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:text="@string/btn_decrypt_verify_file"
android:clickable="true"
android:background="?android:selectableItemBackground"
android:drawableRight="@drawable/ic_save_grey_24dp"
android:drawablePadding="8dp"
android:gravity="center_vertical"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="?android:attr/listDivider"
android:layout_above="@+id/decrypt_file_action_decrypt" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout> </LinearLayout>
</ScrollView>
<!-- TODO: Use this layout later to hide file list -->
<LinearLayout
android:visibility="gone"
android:id="@+id/decrypt_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"></LinearLayout>
<LinearLayout
android:visibility="gone"
android:id="@+id/decrypt_error_overlay"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/decrypt_invalid_text"
android:padding="16dp"
android:layout_gravity="center"
android:textColor="@color/android_red_light" />
<Button
android:id="@+id/decrypt_error_overlay_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/button_edgy"
android:textColor="@color/android_red_light"
android:text="@string/decrypt_invalid_button"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</LinearLayout>