mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-23 17:22:16 -05:00
working DisplayTextActivity, more input support in DecryptActivity
This commit is contained in:
parent
36f3887c5f
commit
b5501eeea6
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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!
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
@ -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> {
|
||||
|
||||
|
@ -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>
|
Loading…
Reference in New Issue
Block a user