working DisplayTextActivity, more input support in DecryptActivity

This commit is contained in:
Vincent Breitmoser 2015-06-20 01:35:33 +02:00
parent 36f3887c5f
commit b5501eeea6
10 changed files with 229 additions and 238 deletions

View File

@ -21,6 +21,7 @@ package org.sufficientlysecure.keychain.pgp;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.text.TextUtils;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
@ -31,6 +32,7 @@ import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.security.SecureRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PgpHelper {
@ -52,9 +54,6 @@ public class PgpHelper {
* <p/>
* TODO: Does this really help on flash storage?
*
* @param context
* @param progressable
* @param file
* @throws IOException
*/
public static void deleteFileSecurely(Context context, Progressable progressable, File file)
@ -78,4 +77,72 @@ public class PgpHelper {
raf.close();
file.delete();
}
/**
* Fixing broken PGP MESSAGE Strings coming from GMail/AOSP Mail
*/
public static String fixPgpMessage(String message) {
// windows newline -> unix newline
message = message.replaceAll("\r\n", "\n");
// Mac OS before X newline -> unix newline
message = message.replaceAll("\r", "\n");
// remove whitespaces before newline
message = message.replaceAll(" +\n", "\n");
// only two consecutive newlines are allowed
message = message.replaceAll("\n\n+", "\n\n");
// replace non breakable spaces
message = message.replaceAll("\\xa0", " ");
return message;
}
/**
* Fixing broken PGP SIGNED MESSAGE Strings coming from GMail/AOSP Mail
*/
public static String fixPgpCleartextSignature(CharSequence input) {
if (!TextUtils.isEmpty(input)) {
String text = input.toString();
// windows newline -> unix newline
text = text.replaceAll("\r\n", "\n");
// Mac OS before X newline -> unix newline
text = text.replaceAll("\r", "\n");
return text;
} else {
return null;
}
}
public static String getPgpContent(CharSequence input) {
// only decrypt if clipboard content is available and a pgp message or cleartext signature
if (!TextUtils.isEmpty(input)) {
Log.dEscaped(Constants.TAG, "input: " + input);
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(input);
if (matcher.matches()) {
String text = matcher.group(1);
text = fixPgpMessage(text);
Log.dEscaped(Constants.TAG, "input fixed: " + text);
return text;
} else {
matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(input);
if (matcher.matches()) {
String text = matcher.group(1);
text = fixPgpCleartextSignature(text);
Log.dEscaped(Constants.TAG, "input fixed: " + text);
return text;
} else {
return null;
}
}
} else {
return null;
}
}
}

View File

@ -32,7 +32,9 @@ import android.widget.Toast;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.provider.TemporaryStorageProvider;
import org.sufficientlysecure.keychain.ui.base.BaseActivity;
@ -42,7 +44,8 @@ public class DecryptActivity extends BaseActivity {
/* Intents */
public static final String ACTION_DECRYPT_DATA = OpenKeychainIntents.DECRYPT_DATA;
// TODO handle this intent
public static final String ACTION_DECRYPT_TEXT = OpenKeychainIntents.DECRYPT_TEXT;
// public static final String ACTION_DECRYPT_TEXT = OpenKeychainIntents.DECRYPT_TEXT;
public static final String ACTION_DECRYPT_FROM_CLIPBOARD = Constants.INTENT_PREFIX + "DECRYPT_DATA_CLIPBOARD";
// intern
public static final String ACTION_DECRYPT_DATA_OPEN = Constants.INTENT_PREFIX + "DECRYPT_DATA_OPEN";
@ -118,6 +121,17 @@ public class DecryptActivity extends BaseActivity {
break;
}
case ACTION_DECRYPT_FROM_CLIPBOARD: {
action = ACTION_DECRYPT_DATA;
CharSequence clipboardText = ClipboardReflection.getClipboardText(this);
String text = PgpHelper.getPgpContent(clipboardText);
Uri uri = readToTempFile(text);
uris.add(uri);
break;
}
case Intent.ACTION_VIEW:
// Android's Action when opening file associated to Keychain (see AndroidManifest.xml)
action = ACTION_DECRYPT_DATA;

View File

@ -61,9 +61,6 @@ public class DecryptFilesInputFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.decrypt_files_input_fragment, container, false);
// hide result view for this fragment
getActivity().findViewById(R.id.result_main_layout).setVisibility(View.GONE);
mFilename = (TextView) view.findViewById(R.id.decrypt_files_filename);
mDecryptButton = view.findViewById(R.id.decrypt_files_action_decrypt);
view.findViewById(R.id.decrypt_files_browse).setOnClickListener(new View.OnClickListener() {

View File

@ -25,15 +25,18 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ViewAnimator;
import org.openintents.openpgp.OpenPgpSignatureResult;
import org.sufficientlysecure.keychain.Constants;
@ -43,24 +46,19 @@ import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.pgp.KeyRing;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainService;
import org.sufficientlysecure.keychain.service.ServiceProgressHandler;
import org.sufficientlysecure.keychain.ui.base.CachingCryptoOperationFragment;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.ui.util.Notify.Style;
import org.sufficientlysecure.keychain.util.Preferences;
public abstract class DecryptFragment
extends CachingCryptoOperationFragment<PgpDecryptVerifyInputParcel, DecryptVerifyResult>
implements LoaderManager.LoaderCallbacks<Cursor> {
public abstract class DecryptFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
public static final int LOADER_ID_UNIFIED = 0;
public static final String ARG_DECRYPT_VERIFY_RESULT = "decrypt_verify_result";
@ -75,11 +73,9 @@ public abstract class DecryptFragment
protected TextView mSignatureEmail;
protected TextView mSignatureAction;
private LinearLayout mContentLayout;
private LinearLayout mErrorOverlayLayout;
private OpenPgpSignatureResult mSignatureResult;
private DecryptVerifyResult mDecryptVerifyResult;
private ViewAnimator mOverlayAnimator;
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
@ -98,18 +94,23 @@ public abstract class DecryptFragment
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);
mOverlayAnimator = (ViewAnimator) view;
Button vErrorOverlayButton = (Button) view.findViewById(R.id.decrypt_error_overlay_button);
vErrorOverlayButton.setOnClickListener(new View.OnClickListener() {
vErrorOverlayButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
mOverlayAnimator.setDisplayedChild(0);
}
});
}
private void showErrorOverlay(boolean overlay) {
int child = overlay ? 1 : 0;
if (mOverlayAnimator.getDisplayedChild() != child) {
mOverlayAnimator.setDisplayedChild(child);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@ -205,9 +206,6 @@ public abstract class DecryptFragment
}
}
/**
* @return returns false if signature is invalid, key is revoked or expired.
*/
protected void loadVerifyResult(DecryptVerifyResult decryptVerifyResult) {
mDecryptVerifyResult = decryptVerifyResult;
@ -227,8 +225,7 @@ public abstract class DecryptFragment
getLoaderManager().destroyLoader(LOADER_ID_UNIFIED);
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
showErrorOverlay(false);
onVerifyLoaded(true);
@ -330,10 +327,7 @@ public abstract class DecryptFragment
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(signatureKeyId);
mErrorOverlayLayout.setVisibility(View.VISIBLE);
mContentLayout.setVisibility(View.GONE);
onVerifyLoaded(false);
onVerifyLoaded(true);
} else if (isExpired) {
mSignatureText.setText(R.string.decrypt_result_signature_expired_key);
@ -342,8 +336,7 @@ public abstract class DecryptFragment
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(signatureKeyId);
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
showErrorOverlay(false);
onVerifyLoaded(true);
@ -355,8 +348,7 @@ public abstract class DecryptFragment
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(signatureKeyId);
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
showErrorOverlay(false);
onVerifyLoaded(true);
@ -367,8 +359,7 @@ public abstract class DecryptFragment
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(signatureKeyId);
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
showErrorOverlay(false);
onVerifyLoaded(true);
@ -379,8 +370,7 @@ public abstract class DecryptFragment
setSignatureLayoutVisibility(View.VISIBLE);
setShowAction(signatureKeyId);
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
showErrorOverlay(false);
onVerifyLoaded(true);
}
@ -438,8 +428,7 @@ public abstract class DecryptFragment
}
});
mErrorOverlayLayout.setVisibility(View.GONE);
mContentLayout.setVisibility(View.VISIBLE);
showErrorOverlay(false);
onVerifyLoaded(true);
@ -452,8 +441,7 @@ public abstract class DecryptFragment
setSignatureLayoutVisibility(View.GONE);
mErrorOverlayLayout.setVisibility(View.VISIBLE);
mContentLayout.setVisibility(View.GONE);
showErrorOverlay(true);
onVerifyLoaded(false);
break;

View File

@ -18,7 +18,13 @@
package org.sufficientlysecure.keychain.ui;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -262,7 +268,7 @@ public class DecryptListFragment
cryptoOperation();
}
private void processResult(final Uri uri, DecryptVerifyResult result) {
private void processResult(final Uri uri, final DecryptVerifyResult result) {
Drawable icon = null;
OnClickListener onFileClick = null, onKeyClick = null;
@ -301,9 +307,59 @@ public class DecryptListFragment
}
Uri outputUri = mOutputUris.get(uri);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(outputUri, metadata.getMimeType());
activity.startActivity(intent);
if ("text/plain".equals(metadata.getMimeType())) {
Intent intent = new Intent(activity, DisplayTextActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(DisplayTextActivity.EXTRA_METADATA, result);
intent.setDataAndType(outputUri, "text/plain");
try {
byte[] decryptedMessage;
{
InputStream in = activity.getContentResolver().openInputStream(outputUri);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[256];
int read;
while ( (read = in.read(buf)) > 0) {
out.write(buf, 0, read);
}
in.close();
out.close();
decryptedMessage = out.toByteArray();
}
String plaintext;
if (result.getCharset() != null) {
try {
plaintext = new String(decryptedMessage, result.getCharset());
} catch (UnsupportedEncodingException e) {
// if we can't decode properly, just fall back to utf-8
plaintext = new String(decryptedMessage);
}
} else {
plaintext = new String(decryptedMessage);
}
intent.putExtra(Intent.EXTRA_TEXT, plaintext);
} catch (IOException e) {
Notify.create(activity, "error", Style.ERROR).show();
return;
}
activity.startActivity(intent);
} else {
Intent intent = new Intent(activity, DisplayTextActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(DisplayTextActivity.EXTRA_METADATA, result);
intent.setDataAndType(outputUri, metadata.getMimeType());
activity.startActivity(intent);
}
}
};
}

View File

@ -30,6 +30,7 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.intents.OpenKeychainIntents;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.operations.results.OperationResult;
import org.sufficientlysecure.keychain.operations.results.SingletonResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
@ -43,11 +44,7 @@ public class DisplayTextActivity extends BaseActivity {
// TODO make this only display text (maybe we need only the fragment?)
/* Intents */
public static final String ACTION_DECRYPT_TEXT = OpenKeychainIntents.DECRYPT_TEXT;
public static final String EXTRA_TEXT = OpenKeychainIntents.DECRYPT_EXTRA_TEXT;
// intern
public static final String ACTION_DECRYPT_FROM_CLIPBOARD = Constants.INTENT_PREFIX + "DECRYPT_TEXT_FROM_CLIPBOARD";
public static final String EXTRA_METADATA = OpenKeychainIntents.DECRYPT_EXTRA_METADATA;
@Override
public void onCreate(Bundle savedInstanceState) {
@ -70,73 +67,6 @@ public class DisplayTextActivity extends BaseActivity {
setContentView(R.layout.decrypt_text_activity);
}
/**
* Fixing broken PGP MESSAGE Strings coming from GMail/AOSP Mail
*/
private String fixPgpMessage(String message) {
// windows newline -> unix newline
message = message.replaceAll("\r\n", "\n");
// Mac OS before X newline -> unix newline
message = message.replaceAll("\r", "\n");
// remove whitespaces before newline
message = message.replaceAll(" +\n", "\n");
// only two consecutive newlines are allowed
message = message.replaceAll("\n\n+", "\n\n");
// replace non breakable spaces
message = message.replaceAll("\\xa0", " ");
return message;
}
/**
* Fixing broken PGP SIGNED MESSAGE Strings coming from GMail/AOSP Mail
*/
private String fixPgpCleartextSignature(CharSequence input) {
if (!TextUtils.isEmpty(input)) {
String text = input.toString();
// windows newline -> unix newline
text = text.replaceAll("\r\n", "\n");
// Mac OS before X newline -> unix newline
text = text.replaceAll("\r", "\n");
return text;
} else {
return null;
}
}
private String getPgpContent(CharSequence input) {
// only decrypt if clipboard content is available and a pgp message or cleartext signature
if (!TextUtils.isEmpty(input)) {
Log.dEscaped(Constants.TAG, "input: " + input);
Matcher matcher = PgpHelper.PGP_MESSAGE.matcher(input);
if (matcher.matches()) {
String text = matcher.group(1);
text = fixPgpMessage(text);
Log.dEscaped(Constants.TAG, "input fixed: " + text);
return text;
} else {
matcher = PgpHelper.PGP_CLEARTEXT_SIGNATURE.matcher(input);
if (matcher.matches()) {
String text = matcher.group(1);
text = fixPgpCleartextSignature(text);
Log.dEscaped(Constants.TAG, "input fixed: " + text);
return text;
} else {
return null;
}
}
} else {
return null;
}
}
/**
* Handles all actions with this intent
*/
@ -153,53 +83,15 @@ public class DisplayTextActivity extends BaseActivity {
return;
}
if (Intent.ACTION_SEND.equals(action) && type != null) {
Log.d(Constants.TAG, "ACTION_SEND");
Log.logDebugBundle(extras, "SEND extras");
Log.d(Constants.TAG, "ACTION_DECRYPT_TEXT");
// When sending to Keychain Decrypt via share menu
if ("text/plain".equals(type)) {
String sharedText = extras.getString(Intent.EXTRA_TEXT);
sharedText = getPgpContent(sharedText);
DecryptVerifyResult result = extras.getParcelable(EXTRA_METADATA);
String plaintext = extras.getString(Intent.EXTRA_TEXT);
if (sharedText != null) {
loadFragment(sharedText);
} else {
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 {
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)) {
Log.d(Constants.TAG, "ACTION_DECRYPT_TEXT");
String extraText = extras.getString(EXTRA_TEXT);
extraText = getPgpContent(extraText);
if (extraText != null) {
loadFragment(extraText);
} else {
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)) {
Log.d(Constants.TAG, "ACTION_DECRYPT_FROM_CLIPBOARD");
CharSequence clipboardText = ClipboardReflection.getClipboardText(this);
String text = getPgpContent(clipboardText);
if (text != null) {
loadFragment(text);
} else {
returnInvalidResult();
}
} else if (ACTION_DECRYPT_TEXT.equals(action)) {
Log.e(Constants.TAG, "Include the extra 'text' in your Intent!");
if (plaintext != null) {
loadFragment(plaintext, result);
} else {
Log.e(Constants.TAG, "EXTRA_TEXT does not contain PGP content!");
Toast.makeText(this, R.string.error_invalid_data, Toast.LENGTH_LONG).show();
finish();
}
@ -214,9 +106,9 @@ public class DisplayTextActivity extends BaseActivity {
finish();
}
private void loadFragment(String ciphertext) {
private void loadFragment(String plaintext, DecryptVerifyResult result) {
// Create an instance of the fragment
Fragment frag = DisplayTextFragment.newInstance(ciphertext);
Fragment frag = DisplayTextFragment.newInstance(plaintext, result);
// Add the fragment to the 'fragment_container' FrameLayout
// NOTE: We use commitAllowingStateLoss() to prevent weird crashes!

View File

@ -31,45 +31,32 @@ import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyInputParcel;
import org.sufficientlysecure.keychain.ui.util.Notify;
import org.sufficientlysecure.keychain.util.ShareHelper;
import java.io.UnsupportedEncodingException;
public class DisplayTextFragment extends DecryptFragment {
public static final String ARG_CIPHERTEXT = "ciphertext";
public static final String ARG_PLAINTEXT = "ciphertext";
public static final String ARG_SHOW_MENU = "show_menu";
// view
private TextView mText;
// model
private String mCiphertext;
private boolean mShowMenuOptions;
private String mPlaintext;
public static DisplayTextFragment newInstance(String ciphertext) {
public static DisplayTextFragment newInstance(String plaintext, DecryptVerifyResult result) {
DisplayTextFragment frag = new DisplayTextFragment();
Bundle args = new Bundle();
args.putString(ARG_CIPHERTEXT, ciphertext);
args.putString(ARG_PLAINTEXT, plaintext);
args.putParcelable(ARG_DECRYPT_VERIFY_RESULT, result);
frag.setArguments(args);
return frag;
}
/**
* Inflate the layout for this fragment
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false);
mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext);
return view;
}
/**
* Create Intent Chooser but exclude decrypt activites
*/
@ -79,7 +66,7 @@ public class DisplayTextFragment extends DecryptFragment {
// we don't want to decrypt the decrypted, no inception ;)
String[] blacklist = new String[]{
Constants.PACKAGE_NAME + ".ui.DecryptTextActivity",
Constants.PACKAGE_NAME + ".ui.DecryptActivity",
"org.thialfihar.android.apg.ui.DecryptActivity"
};
@ -104,13 +91,30 @@ public class DisplayTextFragment extends DecryptFragment {
setHasOptionsMenu(true);
Bundle args = savedInstanceState == null ? getArguments() : savedInstanceState;
mCiphertext = args.getString(ARG_CIPHERTEXT);
Bundle args = getArguments();
mShowMenuOptions = args.getBoolean(ARG_SHOW_MENU, false);
if (savedInstanceState == null) {
cryptoOperation();
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.decrypt_text_fragment, container, false);
mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext);
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle args = getArguments();
String plaintext = args.getString(ARG_PLAINTEXT);
DecryptVerifyResult result = args.getParcelable(ARG_DECRYPT_VERIFY_RESULT);
// display signature result in activity
mText.setText(plaintext);
loadVerifyResult(result);
}
@ -118,12 +122,17 @@ public class DisplayTextFragment extends DecryptFragment {
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(ARG_CIPHERTEXT, mCiphertext);
outState.putBoolean(ARG_SHOW_MENU, mShowMenuOptions);
// no need to save the decrypted text, it's in the textview
}
@Override
protected void onVerifyLoaded(boolean hideErrorOverlay) {
mShowMenuOptions = hideErrorOverlay;
getActivity().supportInvalidateOptionsMenu();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
@ -151,39 +160,4 @@ public class DisplayTextFragment extends DecryptFragment {
return true;
}
@Override
protected PgpDecryptVerifyInputParcel createOperationInput() {
PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(mCiphertext.getBytes());
input.setAllowSymmetricDecryption(true);
return input;
}
@Override
protected void onVerifyLoaded(boolean hideErrorOverlay) {
mShowMenuOptions = hideErrorOverlay;
getActivity().supportInvalidateOptionsMenu();
}
@Override
protected void onCryptoOperationSuccess(DecryptVerifyResult result) {
byte[] decryptedMessage = result.getOutputBytes();
String displayMessage;
if (result.getCharset() != null) {
try {
displayMessage = new String(decryptedMessage, result.getCharset());
} catch (UnsupportedEncodingException e) {
// if we can't decode properly, just fall back to utf-8
displayMessage = new String(decryptedMessage);
}
} else {
displayMessage = new String(decryptedMessage);
}
mText.setText(displayMessage);
// display signature result in activity
loadVerifyResult(result);
}
}

View File

@ -83,8 +83,8 @@ public class EncryptDecryptOverviewFragment extends Fragment {
mDecryptFromClipboard.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent clipboardDecrypt = new Intent(getActivity(), DisplayTextActivity.class);
clipboardDecrypt.setAction(DisplayTextActivity.ACTION_DECRYPT_FROM_CLIPBOARD);
Intent clipboardDecrypt = new Intent(getActivity(), DecryptActivity.class);
clipboardDecrypt.setAction(DecryptActivity.ACTION_DECRYPT_FROM_CLIPBOARD);
startActivityForResult(clipboardDecrypt, 0);
}
});

View File

@ -17,6 +17,14 @@
package org.sufficientlysecure.keychain.ui;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@ -59,13 +67,6 @@ import org.sufficientlysecure.keychain.util.Passphrase;
import org.sufficientlysecure.keychain.util.Preferences;
import org.sufficientlysecure.keychain.util.ShareHelper;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class EncryptFilesFragment
extends CachingCryptoOperationFragment<SignEncryptParcel, SignEncryptResult> {

View File

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_height="match_parent">
<LinearLayout
android:visibility="gone"
@ -63,4 +64,5 @@
android:text="@string/decrypt_invalid_button"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</LinearLayout>
</org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator>