From 56cfb6bc5a5494cb31a3188d6bb4fa53074dbe6a Mon Sep 17 00:00:00 2001 From: Dominik Date: Fri, 16 Nov 2012 16:33:31 +0100 Subject: [PATCH] Rework encrypt for files with intents --- org_apg/AndroidManifest.xml | 25 - org_apg/res/values/strings.xml | 3 +- .../android/apg/helper/FileHelper.java | 48 + .../android/apg/helper/PGPMain.java | 32 +- .../android/apg/service/ApgIntentService.java | 4 +- .../android/apg/ui/DecryptActivity.java | 7 +- .../android/apg/ui/EncryptActivity.java | 1264 +++++++++-------- 7 files changed, 726 insertions(+), 657 deletions(-) diff --git a/org_apg/AndroidManifest.xml b/org_apg/AndroidManifest.xml index 05034de95..1361d3318 100644 --- a/org_apg/AndroidManifest.xml +++ b/org_apg/AndroidManifest.xml @@ -374,31 +374,6 @@ android:name=".provider.ApgServiceBlobProvider" android:authorities="org.thialfihar.android.apg.provider.apgserviceblobprovider" android:permission="org.thialfihar.android.apg.permission.ACCESS_API" /> - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/org_apg/res/values/strings.xml b/org_apg/res/values/strings.xml index fe807e36c..31e3a920e 100644 --- a/org_apg/res/values/strings.xml +++ b/org_apg/res/values/strings.xml @@ -260,7 +260,8 @@ wrong passphrase error saving some key(s) could not extract private key - + Direct binary data without actual file in filesystem is not supported + done. initializing… diff --git a/org_apg/src/org/thialfihar/android/apg/helper/FileHelper.java b/org_apg/src/org/thialfihar/android/apg/helper/FileHelper.java index 7d3185d86..6efee19c0 100644 --- a/org_apg/src/org/thialfihar/android/apg/helper/FileHelper.java +++ b/org_apg/src/org/thialfihar/android/apg/helper/FileHelper.java @@ -16,11 +16,17 @@ package org.thialfihar.android.apg.helper; +import java.net.URISyntaxException; + +import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.util.Log; import android.app.Activity; import android.content.ActivityNotFoundException; +import android.content.Context; import android.content.Intent; +import android.database.Cursor; import android.net.Uri; import android.os.Environment; import android.widget.Toast; @@ -70,4 +76,46 @@ public class FileHelper { Toast.makeText(activity, R.string.noFilemanagerInstalled, Toast.LENGTH_SHORT).show(); } } + + /** + * Get a file path from a Uri. + * + * from https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/ + * afilechooser/utils/FileUtils.java + * + * @param context + * @param uri + * @return + * + * @author paulburke + */ + public static String getPath(Context context, Uri uri) { + + Log.d(Constants.TAG + " File -", + "Authority: " + uri.getAuthority() + ", Fragment: " + uri.getFragment() + + ", Port: " + uri.getPort() + ", Query: " + uri.getQuery() + ", Scheme: " + + uri.getScheme() + ", Host: " + uri.getHost() + ", Segments: " + + uri.getPathSegments().toString()); + + if ("content".equalsIgnoreCase(uri.getScheme())) { + String[] projection = { "_data" }; + Cursor cursor = null; + + try { + cursor = context.getContentResolver().query(uri, projection, null, null, null); + int column_index = cursor.getColumnIndexOrThrow("_data"); + if (cursor.moveToFirst()) { + return cursor.getString(column_index); + } + } catch (Exception e) { + // Eat it + } + } + + else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return null; + } } diff --git a/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java b/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java index db9305ffa..0cde19ae5 100644 --- a/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java +++ b/org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java @@ -1746,12 +1746,15 @@ public class PGPMain { return "APG v" + getVersion(context); } - public static String generateRandomString(int length) { + /** + * Generate a random filename + * + * @param length + * @return + */ + public static String generateRandomFilename(int length) { SecureRandom random = new SecureRandom(); - /* - * try { random = SecureRandom.getInstance("SHA1PRNG", new BouncyCastleProvider()); } catch - * (NoSuchAlgorithmException e) { // TODO: need to handle this case somehow return null; } - */ + byte bytes[] = new byte[length]; random.nextBytes(bytes); String result = ""; @@ -1772,6 +1775,14 @@ public class PGPMain { return result; } + /** + * Go once through stream to get length of stream. The length is later used to display progress + * when encrypting/decrypting + * + * @param in + * @return + * @throws IOException + */ public static long getLengthOfStream(InputStream in) throws IOException { long size = 0; long n = 0; @@ -1782,6 +1793,17 @@ public class PGPMain { return size; } + /** + * Deletes file securely by overwriting it with random data before deleting it. + * + * TODO: Does this really help on flash storage? + * + * @param context + * @param progress + * @param file + * @throws FileNotFoundException + * @throws IOException + */ public static void deleteFileSecurely(Context context, ProgressDialogUpdater progress, File file) throws FileNotFoundException, IOException { long length = file.length(); diff --git a/org_apg/src/org/thialfihar/android/apg/service/ApgIntentService.java b/org_apg/src/org/thialfihar/android/apg/service/ApgIntentService.java index e3290ae65..8a6ca6b4c 100644 --- a/org_apg/src/org/thialfihar/android/apg/service/ApgIntentService.java +++ b/org_apg/src/org/thialfihar/android/apg/service/ApgIntentService.java @@ -295,7 +295,7 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd // OutputStream try { while (true) { - streamFilename = PGPMain.generateRandomString(32); + streamFilename = PGPMain.generateRandomFilename(32); if (streamFilename == null) { throw new PGPMain.ApgGeneralException( "couldn't generate random file name"); @@ -448,7 +448,7 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd // OutputStream try { while (true) { - streamFilename = PGPMain.generateRandomString(32); + streamFilename = PGPMain.generateRandomFilename(32); if (streamFilename == null) { throw new PGPMain.ApgGeneralException( "couldn't generate random file name"); diff --git a/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java index a6b10c521..f1de44312 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java @@ -254,11 +254,12 @@ public class DecryptActivity extends SherlockFragmentActivity { String action = intent.getAction(); String type = intent.getType(); - mContentUri = intent.getData(); - if (Intent.ACTION_VIEW.equals(action)) { // Android's Action when opening file associated to APG (see AndroidManifest.xml) + // This gets the Uri, where an inputStream can be opened from + mContentUri = intent.getData(); + // TODO: old implementation of ACTION_VIEW. Is this used in K9? // Uri uri = mIntent.getData(); // try { @@ -893,7 +894,7 @@ public class DecryptActivity extends SherlockFragmentActivity { case Id.request.filename: { if (resultCode == RESULT_OK && data != null) { try { - String path = data.getData().getPath(); + String path = FileHelper.getPath(this, data.getData()); Log.d(Constants.TAG, "path=" + path); mFilename.setText(path); diff --git a/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java index ec7f26883..8879034cb 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java @@ -72,12 +72,15 @@ public class EncryptActivity extends SherlockFragmentActivity { // possible intent actions for this activity public static final String ACTION_ENCRYPT = Constants.INTENT_PREFIX + "ENCRYPT"; - public static final String ACTION_ENCRYPT_FILE = Constants.INTENT_PREFIX + "ENCRYPT_FILE"; public static final String ACTION_ENCRYPT_AND_RETURN = Constants.INTENT_PREFIX + "ENCRYPT_AND_RETURN"; - public static final String ACTION_GENERATE_SIGNATURE = Constants.INTENT_PREFIX + public static final String ACTION_GENERATE_SIGNATURE_AND_RETURN = Constants.INTENT_PREFIX + "GENERATE_SIGNATURE"; + public static final String ACTION_ENCRYPT_STREAM = Constants.INTENT_PREFIX + "ENCRYPT_STREAM"; + public static final String ACTION_ENCRYPT_STREAM_AND_RETURN = Constants.INTENT_PREFIX + + "ENCRYPT_STREAM_AND_RETURN"; + // possible extra keys public static final String EXTRA_TEXT = "text"; public static final String EXTRA_DATA = "data"; @@ -131,7 +134,7 @@ public class EncryptActivity extends SherlockFragmentActivity { private boolean mAsciiArmourDemand = false; private boolean mOverrideAsciiArmour = false; - private Uri mContentUri = null; + private Uri mIntentDataUri = null; private byte[] mData = null; private boolean mGenerateSignature = false; @@ -140,14 +143,6 @@ public class EncryptActivity extends SherlockFragmentActivity { private FileDialogFragment mFileDialog; - public void setSecretKeyId(long id) { - mSecretKeyId = id; - } - - public long getSecretKeyId() { - return mSecretKeyId; - } - /** * ActionBar menu is created based on class variables to change it at runtime * @@ -200,7 +195,7 @@ public class EncryptActivity extends SherlockFragmentActivity { // check permissions for intent actions without user interaction String[] restrictedActions = new String[] { ACTION_ENCRYPT_AND_RETURN, - ACTION_GENERATE_SIGNATURE }; + ACTION_GENERATE_SIGNATURE_AND_RETURN, ACTION_ENCRYPT_STREAM_AND_RETURN }; OtherHelper.checkPackagePermissionForActions(this, this.getCallingPackage(), Constants.PERMISSION_ACCESS_API, getIntent().getAction(), restrictedActions); @@ -209,8 +204,635 @@ public class EncryptActivity extends SherlockFragmentActivity { // set actionbar without home button if called from another app OtherHelper.setActionBarBackButton(this); - mGenerateSignature = false; + initView(); + // Handle intent actions + handleActions(getIntent()); + + updateView(); + updateSource(); + updateMode(); + + if (mReturnResult) { + mSourcePrevious.setClickable(false); + mSourcePrevious.setEnabled(false); + mSourcePrevious.setVisibility(View.INVISIBLE); + + mSourceNext.setClickable(false); + mSourceNext.setEnabled(false); + mSourceNext.setVisibility(View.INVISIBLE); + + mSourceLabel.setClickable(false); + mSourceLabel.setEnabled(false); + } + + updateActionBarButtons(); + + if (mReturnResult + && (mMessage.getText().length() > 0 || mData != null) + && ((mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) || mSecretKeyId != 0)) { + encryptClicked(); + } + } + + /** + * Handles all actions with this intent + * + * @param intent + */ + private void handleActions(Intent intent) { + String action = intent.getAction(); + Bundle extras = intent.getExtras(); + String type = intent.getType(); + Uri uri = intent.getData(); + + if (extras == null) { + extras = new Bundle(); + } + + if (Intent.ACTION_SEND.equals(action) && type != null) { + // Android's Action when sending to APG Encrypt + + if ("text/plain".equals(type)) { + // plain text + String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); + if (sharedText != null) { + // handle like normal text encryption, override action and extras + action = ACTION_ENCRYPT; + extras.putString(EXTRA_TEXT, sharedText); + extras.putBoolean(EXTRA_ASCII_ARMOUR, true); + } + } else { + // files via content provider, override uri and action + uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM); + action = ACTION_ENCRYPT_STREAM; + } + } + + if (ACTION_ENCRYPT_AND_RETURN.equals(action) + || ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) { + mReturnResult = true; + } + + if (ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) { + mGenerateSignature = true; + mOverrideAsciiArmour = true; + mAsciiArmourDemand = false; + } + + if (extras.containsKey(EXTRA_ASCII_ARMOUR)) { + mAsciiArmourDemand = extras.getBoolean(EXTRA_ASCII_ARMOUR, true); + mOverrideAsciiArmour = true; + mAsciiArmour.setChecked(mAsciiArmourDemand); + } + + mData = extras.getByteArray(EXTRA_DATA); + String textData = null; + if (mData == null) { + textData = extras.getString(EXTRA_TEXT); + } + mSendTo = extras.getString(EXTRA_SEND_TO); + mSubject = extras.getString(EXTRA_SUBJECT); + long signatureKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID); + long[] encryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); + + // preselect keys given by intent + preselectKeys(signatureKeyId, encryptionKeyIds); + + if (ACTION_ENCRYPT.equals(action) || ACTION_ENCRYPT_AND_RETURN.equals(action) + || ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) { + if (textData != null) { + mMessage.setText(textData); + } + mSource.setInAnimation(null); + mSource.setOutAnimation(null); + while (mSource.getCurrentView().getId() != R.id.sourceMessage) { + mSource.showNext(); + } + } else if (ACTION_ENCRYPT_STREAM.equals(action)) { + // get file path from uri + String path = FileHelper.getPath(this, uri); + + if (path != null) { + mInputFilename = path; + mFilename.setText(mInputFilename); + + mSource.setInAnimation(null); + mSource.setOutAnimation(null); + while (mSource.getCurrentView().getId() != R.id.sourceFile) { + mSource.showNext(); + } + } else { + Log.e(Constants.TAG, + "Direct binary data without actual file in filesystem is not supported"); + Toast.makeText(this, R.string.error_onlyFilesAreSupported, Toast.LENGTH_LONG) + .show(); + // end activity + finish(); + } + + } else if (ACTION_ENCRYPT_STREAM_AND_RETURN.equals(action)) { + // use mIntentDataUri to encrypt any stream and return + // TODO + } + } + + /** + * If an Intent gives a signatureKeyId and/or encryptionKeyIds, preselect those! + * + * @param preselectedSignatureKeyId + * @param preselectedEncryptionKeyIds + */ + private void preselectKeys(long preselectedSignatureKeyId, long[] preselectedEncryptionKeyIds) { + if (preselectedSignatureKeyId != 0) { + PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, + preselectedSignatureKeyId); + PGPSecretKey masterKey = null; + if (keyRing != null) { + masterKey = PGPHelper.getMasterKey(keyRing); + if (masterKey != null) { + Vector signKeys = PGPHelper.getUsableSigningKeys(keyRing); + if (signKeys.size() > 0) { + mSecretKeyId = masterKey.getKeyID(); + } + } + } + } + + if (preselectedEncryptionKeyIds != null) { + Vector goodIds = new Vector(); + for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) { + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, + preselectedEncryptionKeyIds[i]); + PGPPublicKey masterKey = null; + if (keyRing == null) { + continue; + } + masterKey = PGPHelper.getMasterKey(keyRing); + if (masterKey == null) { + continue; + } + Vector encryptKeys = PGPHelper.getUsableEncryptKeys(keyRing); + if (encryptKeys.size() == 0) { + continue; + } + goodIds.add(masterKey.getKeyID()); + } + if (goodIds.size() > 0) { + mEncryptionKeyIds = new long[goodIds.size()]; + for (int i = 0; i < goodIds.size(); ++i) { + mEncryptionKeyIds[i] = goodIds.get(i); + } + } + } + } + + /** + * Guess output filename based on input path + * + * @param path + * @return Suggestion for output filename + */ + private String guessOutputFilename(String path) { + // output in the same directory but with additional ending + File file = new File(path); + String ending = (mAsciiArmour.isChecked() ? ".asc" : ".gpg"); + String outputFilename = file.getParent() + File.separator + file.getName() + ending; + + return outputFilename; + } + + private void updateSource() { + switch (mSource.getCurrentView().getId()) { + case R.id.sourceFile: { + mSourceLabel.setText(R.string.label_file); + break; + } + + case R.id.sourceMessage: { + mSourceLabel.setText(R.string.label_message); + break; + } + + default: { + break; + } + } + updateActionBarButtons(); + } + + /** + * Set ActionBar buttons based on parameters + * + * @param encryptEnabled + * @param encryptStringRes + * @param encryptToClipboardEnabled + * @param encryptToClipboardStringRes + */ + private void setActionbarButtons(boolean encryptEnabled, int encryptStringRes, + boolean encryptToClipboardEnabled, int encryptToClipboardStringRes) { + mEncryptEnabled = encryptEnabled; + if (encryptEnabled) { + mEncryptString = getString(encryptStringRes); + } + mEncryptToClipboardEnabled = encryptToClipboardEnabled; + if (encryptToClipboardEnabled) { + mEncryptToClipboardString = getString(encryptToClipboardStringRes); + } + + // build new action bar based on these class variables + invalidateOptionsMenu(); + } + + /** + * Update ActionBar buttons based on current selection in view + */ + private void updateActionBarButtons() { + switch (mSource.getCurrentView().getId()) { + case R.id.sourceFile: { + setActionbarButtons(true, R.string.btn_encryptFile, false, 0); + + break; + } + + case R.id.sourceMessage: { + mSourceLabel.setText(R.string.label_message); + + if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { + if (mReturnResult) { + setActionbarButtons(true, R.string.btn_encrypt, false, 0); + } else { + setActionbarButtons(true, R.string.btn_encryptAndEmail, true, + R.string.btn_encryptToClipboard); + } + } else { + if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { + if (mSecretKeyId == 0) { + setActionbarButtons(false, 0, false, 0); + } else { + if (mReturnResult) { + setActionbarButtons(true, R.string.btn_sign, false, 0); + } else { + setActionbarButtons(true, R.string.btn_signAndEmail, true, + R.string.btn_signToClipboard); + } + } + } else { + if (mReturnResult) { + setActionbarButtons(true, R.string.btn_encrypt, false, 0); + } else { + setActionbarButtons(true, R.string.btn_encryptAndEmail, true, + R.string.btn_encryptToClipboard); + } + } + } + break; + } + + default: { + break; + } + } + + } + + private void updateMode() { + switch (mMode.getCurrentView().getId()) { + case R.id.modeAsymmetric: { + mModeLabel.setText(R.string.label_asymmetric); + break; + } + + case R.id.modeSymmetric: { + mModeLabel.setText(R.string.label_symmetric); + break; + } + + default: { + break; + } + } + updateActionBarButtons(); + } + + private void encryptToClipboardClicked() { + mEncryptTarget = Id.target.clipboard; + initiateEncryption(); + } + + private void encryptClicked() { + Log.d(Constants.TAG, "encryptClicked invoked!"); + + if (mSource.getCurrentView().getId() == R.id.sourceFile) { + mEncryptTarget = Id.target.file; + } else { + mEncryptTarget = Id.target.email; + } + initiateEncryption(); + } + + private void initiateEncryption() { + if (mEncryptTarget == Id.target.file) { + String currentFilename = mFilename.getText().toString(); + if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { + mInputFilename = mFilename.getText().toString(); + } + + mOutputFilename = guessOutputFilename(mInputFilename); + + if (mInputFilename.equals("")) { + Toast.makeText(this, R.string.noFileSelected, Toast.LENGTH_SHORT).show(); + return; + } + + if (!mInputFilename.startsWith("content")) { + File file = new File(mInputFilename); + if (!file.exists() || !file.isFile()) { + Toast.makeText( + this, + getString(R.string.errorMessage, getString(R.string.error_fileNotFound)), + Toast.LENGTH_SHORT).show(); + return; + } + } + } + + // symmetric encryption + if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { + boolean gotPassPhrase = false; + String passPhrase = mPassPhrase.getText().toString(); + String passPhraseAgain = mPassPhraseAgain.getText().toString(); + if (!passPhrase.equals(passPhraseAgain)) { + Toast.makeText(this, R.string.passPhrasesDoNotMatch, Toast.LENGTH_SHORT).show(); + return; + } + + gotPassPhrase = (passPhrase.length() != 0); + if (!gotPassPhrase) { + Toast.makeText(this, R.string.passPhraseMustNotBeEmpty, Toast.LENGTH_SHORT).show(); + return; + } + } else { + boolean encryptIt = (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0); + // for now require at least one form of encryption for files + if (!encryptIt && mEncryptTarget == Id.target.file) { + Toast.makeText(this, R.string.selectEncryptionKey, Toast.LENGTH_SHORT).show(); + return; + } + + if (!encryptIt && mSecretKeyId == 0) { + Toast.makeText(this, R.string.selectEncryptionOrSignatureKey, Toast.LENGTH_SHORT) + .show(); + return; + } + + if (mSecretKeyId != 0 + && PassphraseCacheService.getCachedPassphrase(this, mSecretKeyId) == null) { + showPassphraseDialog(); + + return; + } + } + + if (mEncryptTarget == Id.target.file) { + showOutputFileDialog(); + } else { + encryptStart(); + } + } + + /** + * Shows passphrase dialog to cache a new passphrase the user enters for using it later for + * encryption + */ + private void showPassphraseDialog() { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + if (mEncryptTarget == Id.target.file) { + showOutputFileDialog(); + } else { + encryptStart(); + } + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + try { + PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance( + EncryptActivity.this, messenger, mSecretKeyId); + + passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); + } catch (PGPMain.ApgGeneralException e) { + Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); + // send message to handler to start encryption directly + returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); + } + } + + private void showOutputFileDialog() { + // Message is received after file is selected + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == FileDialogFragment.MESSAGE_OKAY) { + Bundle data = message.getData(); + mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); + encryptStart(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + mFileDialog = FileDialogFragment.newInstance(messenger, + getString(R.string.title_encryptToFile), + getString(R.string.specifyFileToEncryptTo), mOutputFilename, null, + Id.request.output_filename); + + mFileDialog.show(getSupportFragmentManager(), "fileDialog"); + } + + private void encryptStart() { + // Send all information needed to service to edit key in other thread + Intent intent = new Intent(this, ApgIntentService.class); + + // fill values for this action + Bundle data = new Bundle(); + + boolean useAsciiArmor = true; + long encryptionKeyIds[] = null; + int compressionId = 0; + boolean signOnly = false; + + if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { + Log.d(Constants.TAG, "Symmetric encryption enabled!"); + String passPhrase = mPassPhrase.getText().toString(); + if (passPhrase.length() == 0) { + passPhrase = null; + } + + data.putString(ApgIntentService.SYMMETRIC_PASSPHRASE, passPhrase); + } else { + encryptionKeyIds = mEncryptionKeyIds; + signOnly = (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0); + } + + intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_ENCRYPT_SIGN); + + // choose default settings, target and data bundle by target + if (mIntentDataUri != null) { + data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_STREAM); + data.putParcelable(ApgIntentService.PROVIDER_URI, mIntentDataUri); + + } else if (mEncryptTarget == Id.target.file) { + useAsciiArmor = mAsciiArmour.isChecked(); + compressionId = ((Choice) mFileCompression.getSelectedItem()).getId(); + + data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_FILE); + + Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" + + mOutputFilename); + + data.putString(ApgIntentService.INPUT_FILE, mInputFilename); + data.putString(ApgIntentService.OUTPUT_FILE, mOutputFilename); + + } else { + useAsciiArmor = true; + compressionId = Preferences.getPreferences(this).getDefaultMessageCompression(); + + data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_BYTES); + + if (mData != null) { + data.putByteArray(ApgIntentService.MESSAGE_BYTES, mData); + } else { + String message = mMessage.getText().toString(); + if (signOnly && !mReturnResult) { + fixBadCharactersForGmail(message); + } + data.putByteArray(ApgIntentService.MESSAGE_BYTES, message.getBytes()); + } + } + + if (mOverrideAsciiArmour) { + useAsciiArmor = mAsciiArmourDemand; + } + + data.putLong(ApgIntentService.SECRET_KEY_ID, mSecretKeyId); + data.putBoolean(ApgIntentService.USE_ASCII_AMOR, useAsciiArmor); + data.putLongArray(ApgIntentService.ENCRYPTION_KEYS_IDS, encryptionKeyIds); + data.putInt(ApgIntentService.COMPRESSION_ID, compressionId); + data.putBoolean(ApgIntentService.GENERATE_SIGNATURE, mGenerateSignature); + data.putBoolean(ApgIntentService.SIGN_ONLY, signOnly); + + intent.putExtra(ApgIntentService.EXTRA_DATA, data); + + // Message is received after encrypting is done in ApgService + ApgIntentServiceHandler saveHandler = new ApgIntentServiceHandler(this, + R.string.progress_encrypting, ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard ApgHandler first + super.handleMessage(message); + + if (message.arg1 == ApgIntentServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle data = message.getData(); + + String output; + switch (mEncryptTarget) { + case Id.target.clipboard: + output = data.getString(ApgIntentService.RESULT_ENCRYPTED_STRING); + Log.d(Constants.TAG, "output: " + output); + Compatibility.copyToClipboard(EncryptActivity.this, output); + Toast.makeText(EncryptActivity.this, + R.string.encryptionToClipboardSuccessful, Toast.LENGTH_SHORT) + .show(); + break; + + case Id.target.email: + if (mReturnResult) { + Intent intent = new Intent(); + intent.putExtras(data); + setResult(RESULT_OK, intent); + finish(); + return; + } + + output = data.getString(ApgIntentService.RESULT_ENCRYPTED_STRING); + Log.d(Constants.TAG, "output: " + output); + + Intent emailIntent = new Intent(Intent.ACTION_SEND); + emailIntent.setType("text/plain; charset=utf-8"); + emailIntent.putExtra(Intent.EXTRA_TEXT, output); + if (mSubject != null) { + emailIntent.putExtra(Intent.EXTRA_SUBJECT, mSubject); + } + if (mSendTo != null) { + emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { mSendTo }); + } + startActivity(Intent.createChooser(emailIntent, + getString(R.string.title_sendEmail))); + break; + + case Id.target.file: + Toast.makeText(EncryptActivity.this, R.string.encryptionSuccessful, + Toast.LENGTH_SHORT).show(); + + if (mDeleteAfter.isChecked()) { + // Create and show dialog to delete original file + DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment + .newInstance(mInputFilename); + deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); + } + break; + + default: + // shouldn't happen + break; + + } + } + }; + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(ApgIntentService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(this); + + // start service with intent + startService(intent); + } + + /** + * Fixes bad message characters for gmail + * + * @param message + * @return + */ + private String fixBadCharactersForGmail(String message) { + // fix the message a bit, trailing spaces and newlines break stuff, + // because GMail sends as HTML and such things fuck up the + // signature, + // TODO: things like "<" and ">" also fuck up the signature + message = message.replaceAll(" +\n", "\n"); + message = message.replaceAll("\n\n+", "\n\n"); + message = message.replaceFirst("^\n+", ""); + // make sure there'll be exactly one newline at the end + message = message.replaceFirst("\n*$", "\n"); + + return message; + } + + private void initView() { mSource = (ViewFlipper) findViewById(R.id.source); mSourceLabel = (TextView) findViewById(R.id.sourceLabel); mSourcePrevious = (ImageView) findViewById(R.id.sourcePrevious); @@ -326,11 +948,6 @@ public class EncryptActivity extends SherlockFragmentActivity { mAsciiArmour = (CheckBox) findViewById(R.id.asciiArmour); mAsciiArmour.setChecked(Preferences.getPreferences(this).getDefaultAsciiArmour()); - mAsciiArmour.setOnClickListener(new OnClickListener() { - public void onClick(View view) { - guessOutputFilename(); - } - }); mSelectKeysButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { @@ -344,606 +961,11 @@ public class EncryptActivity extends SherlockFragmentActivity { if (checkBox.isChecked()) { selectSecretKey(); } else { - setSecretKeyId(Id.key.none); + mSecretKeyId = Id.key.none; updateView(); } } }); - - // Get intent, action and MIME type - Intent intent = getIntent(); - String action = intent.getAction(); - String type = intent.getType(); - mContentUri = intent.getData(); - - if (Intent.ACTION_SEND.equals(action) && type != null) { - // Android's Action when sending to APG Encrypt - - if ("text/plain".equals(type)) { - // plain text - String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); - if (sharedText != null) { - intent.setAction(ACTION_ENCRYPT); - intent.putExtra(EXTRA_TEXT, sharedText); - intent.putExtra(EXTRA_ASCII_ARMOUR, true); - handleActionEncryptSign(intent); - } - } else { - // binary via content provider (could also be files) - Uri uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM); - if (uri != null) { - mContentUri = uri; - handleActionEncryptSign(intent); - } - } - } else if (ACTION_ENCRYPT.equals(action) || ACTION_ENCRYPT_FILE.equals(action) - || ACTION_ENCRYPT_AND_RETURN.equals(action) - || ACTION_GENERATE_SIGNATURE.equals(action)) { - // APG's own Actions - - handleActionEncryptSign(intent); - } - - updateView(); - updateSource(); - updateMode(); - - if (mReturnResult) { - mSourcePrevious.setClickable(false); - mSourcePrevious.setEnabled(false); - mSourcePrevious.setVisibility(View.INVISIBLE); - - mSourceNext.setClickable(false); - mSourceNext.setEnabled(false); - mSourceNext.setVisibility(View.INVISIBLE); - - mSourceLabel.setClickable(false); - mSourceLabel.setEnabled(false); - } - - updateActionBarButtons(); - - if (mReturnResult - && (mMessage.getText().length() > 0 || mData != null || mContentUri != null) - && ((mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) || getSecretKeyId() != 0)) { - encryptClicked(); - } - } - - /** - * Handles all actions with this intent - * - * @param intent - */ - private void handleActionEncryptSign(Intent intent) { - String action = intent.getAction(); - Bundle extras = intent.getExtras(); - if (extras == null) { - extras = new Bundle(); - } - - if (ACTION_ENCRYPT_AND_RETURN.equals(action) || ACTION_GENERATE_SIGNATURE.equals(action)) { - mReturnResult = true; - } - - if (ACTION_GENERATE_SIGNATURE.equals(action)) { - mGenerateSignature = true; - mOverrideAsciiArmour = true; - mAsciiArmourDemand = false; - } - - if (extras.containsKey(EXTRA_ASCII_ARMOUR)) { - mAsciiArmourDemand = extras.getBoolean(EXTRA_ASCII_ARMOUR, true); - mOverrideAsciiArmour = true; - mAsciiArmour.setChecked(mAsciiArmourDemand); - } - - mData = extras.getByteArray(EXTRA_DATA); - String textData = null; - if (mData == null) { - textData = extras.getString(EXTRA_TEXT); - } - mSendTo = extras.getString(EXTRA_SEND_TO); - mSubject = extras.getString(EXTRA_SUBJECT); - long signatureKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID); - long encryptionKeyIds[] = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); - if (signatureKeyId != 0) { - PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, - signatureKeyId); - PGPSecretKey masterKey = null; - if (keyRing != null) { - masterKey = PGPHelper.getMasterKey(keyRing); - if (masterKey != null) { - Vector signKeys = PGPHelper.getUsableSigningKeys(keyRing); - if (signKeys.size() > 0) { - setSecretKeyId(masterKey.getKeyID()); - } - } - } - } - - if (encryptionKeyIds != null) { - Vector goodIds = new Vector(); - for (int i = 0; i < encryptionKeyIds.length; ++i) { - PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, - encryptionKeyIds[i]); - PGPPublicKey masterKey = null; - if (keyRing == null) { - continue; - } - masterKey = PGPHelper.getMasterKey(keyRing); - if (masterKey == null) { - continue; - } - Vector encryptKeys = PGPHelper.getUsableEncryptKeys(keyRing); - if (encryptKeys.size() == 0) { - continue; - } - goodIds.add(masterKey.getKeyID()); - } - if (goodIds.size() > 0) { - mEncryptionKeyIds = new long[goodIds.size()]; - for (int i = 0; i < goodIds.size(); ++i) { - mEncryptionKeyIds[i] = goodIds.get(i); - } - } - } - - if (ACTION_ENCRYPT.equals(action) || ACTION_ENCRYPT_AND_RETURN.equals(action) - || ACTION_GENERATE_SIGNATURE.equals(action)) { - if (textData != null) { - mMessage.setText(textData); - } - mSource.setInAnimation(null); - mSource.setOutAnimation(null); - while (mSource.getCurrentView().getId() != R.id.sourceMessage) { - mSource.showNext(); - } - } else if (ACTION_ENCRYPT_FILE.equals(action)) { - mInputFilename = intent.getData().getPath(); - mFilename.setText(mInputFilename); - guessOutputFilename(); - mSource.setInAnimation(null); - mSource.setOutAnimation(null); - while (mSource.getCurrentView().getId() != R.id.sourceFile) { - mSource.showNext(); - } - } - } - - private void guessOutputFilename() { - mInputFilename = mFilename.getText().toString(); - File file = new File(mInputFilename); - String ending = (mAsciiArmour.isChecked() ? ".asc" : ".gpg"); - mOutputFilename = Constants.path.APP_DIR + "/" + file.getName() + ending; - } - - private void updateSource() { - switch (mSource.getCurrentView().getId()) { - case R.id.sourceFile: { - mSourceLabel.setText(R.string.label_file); - break; - } - - case R.id.sourceMessage: { - mSourceLabel.setText(R.string.label_message); - break; - } - - default: { - break; - } - } - updateActionBarButtons(); - } - - /** - * Set ActionBar buttons based on parameters - * - * @param encryptEnabled - * @param encryptStringRes - * @param encryptToClipboardEnabled - * @param encryptToClipboardStringRes - */ - private void setActionbarButtons(boolean encryptEnabled, int encryptStringRes, - boolean encryptToClipboardEnabled, int encryptToClipboardStringRes) { - mEncryptEnabled = encryptEnabled; - if (encryptEnabled) { - mEncryptString = getString(encryptStringRes); - } - mEncryptToClipboardEnabled = encryptToClipboardEnabled; - if (encryptToClipboardEnabled) { - mEncryptToClipboardString = getString(encryptToClipboardStringRes); - } - - // build new action bar based on these class variables - invalidateOptionsMenu(); - } - - /** - * Update ActionBar buttons based on current selection in view - */ - private void updateActionBarButtons() { - switch (mSource.getCurrentView().getId()) { - case R.id.sourceFile: { - setActionbarButtons(true, R.string.btn_encryptFile, false, 0); - - break; - } - - case R.id.sourceMessage: { - mSourceLabel.setText(R.string.label_message); - - if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { - if (mReturnResult) { - setActionbarButtons(true, R.string.btn_encrypt, false, 0); - } else { - setActionbarButtons(true, R.string.btn_encryptAndEmail, true, - R.string.btn_encryptToClipboard); - } - } else { - if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { - if (getSecretKeyId() == 0) { - setActionbarButtons(false, 0, false, 0); - } else { - if (mReturnResult) { - setActionbarButtons(true, R.string.btn_sign, false, 0); - } else { - setActionbarButtons(true, R.string.btn_signAndEmail, true, - R.string.btn_signToClipboard); - } - } - } else { - if (mReturnResult) { - setActionbarButtons(true, R.string.btn_encrypt, false, 0); - } else { - setActionbarButtons(true, R.string.btn_encryptAndEmail, true, - R.string.btn_encryptToClipboard); - } - } - } - break; - } - - default: { - break; - } - } - - } - - private void updateMode() { - switch (mMode.getCurrentView().getId()) { - case R.id.modeAsymmetric: { - mModeLabel.setText(R.string.label_asymmetric); - break; - } - - case R.id.modeSymmetric: { - mModeLabel.setText(R.string.label_symmetric); - break; - } - - default: { - break; - } - } - updateActionBarButtons(); - } - - private void encryptToClipboardClicked() { - mEncryptTarget = Id.target.clipboard; - initiateEncryption(); - } - - private void encryptClicked() { - Log.d(Constants.TAG, "encryptClicked invoked!"); - - if (mSource.getCurrentView().getId() == R.id.sourceFile) { - mEncryptTarget = Id.target.file; - } else { - mEncryptTarget = Id.target.email; - } - initiateEncryption(); - } - - private void initiateEncryption() { - if (mEncryptTarget == Id.target.file) { - String currentFilename = mFilename.getText().toString(); - if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { - guessOutputFilename(); - } - - if (mInputFilename.equals("")) { - Toast.makeText(this, R.string.noFileSelected, Toast.LENGTH_SHORT).show(); - return; - } - - if (!mInputFilename.startsWith("content")) { - File file = new File(mInputFilename); - if (!file.exists() || !file.isFile()) { - Toast.makeText( - this, - getString(R.string.errorMessage, getString(R.string.error_fileNotFound)), - Toast.LENGTH_SHORT).show(); - return; - } - } - } - - // symmetric encryption - if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { - boolean gotPassPhrase = false; - String passPhrase = mPassPhrase.getText().toString(); - String passPhraseAgain = mPassPhraseAgain.getText().toString(); - if (!passPhrase.equals(passPhraseAgain)) { - Toast.makeText(this, R.string.passPhrasesDoNotMatch, Toast.LENGTH_SHORT).show(); - return; - } - - gotPassPhrase = (passPhrase.length() != 0); - if (!gotPassPhrase) { - Toast.makeText(this, R.string.passPhraseMustNotBeEmpty, Toast.LENGTH_SHORT).show(); - return; - } - } else { - boolean encryptIt = (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0); - // for now require at least one form of encryption for files - if (!encryptIt && mEncryptTarget == Id.target.file) { - Toast.makeText(this, R.string.selectEncryptionKey, Toast.LENGTH_SHORT).show(); - return; - } - - if (!encryptIt && getSecretKeyId() == 0) { - Toast.makeText(this, R.string.selectEncryptionOrSignatureKey, Toast.LENGTH_SHORT) - .show(); - return; - } - - if (getSecretKeyId() != 0 - && PassphraseCacheService.getCachedPassphrase(this, getSecretKeyId()) == null) { - showPassphraseDialog(); - - return; - } - } - - if (mEncryptTarget == Id.target.file) { - showOutputFileDialog(); - } else { - encryptStart(); - } - } - - /** - * Shows passphrase dialog to cache a new passphrase the user enters for using it later for - * encryption - */ - private void showPassphraseDialog() { - // Message is received after passphrase is cached - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - if (mEncryptTarget == Id.target.file) { - showOutputFileDialog(); - } else { - encryptStart(); - } - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - try { - PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance( - EncryptActivity.this, messenger, mSecretKeyId); - - passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); - } catch (PGPMain.ApgGeneralException e) { - Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); - // send message to handler to start encryption directly - returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); - } - } - - private void showOutputFileDialog() { - // Message is received after file is selected - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == FileDialogFragment.MESSAGE_OKAY) { - Bundle data = message.getData(); - mOutputFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); - encryptStart(); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - mFileDialog = FileDialogFragment.newInstance(messenger, - getString(R.string.title_encryptToFile), - getString(R.string.specifyFileToEncryptTo), mOutputFilename, null, - Id.request.output_filename); - - mFileDialog.show(getSupportFragmentManager(), "fileDialog"); - } - - private void encryptStart() { - // Send all information needed to service to edit key in other thread - Intent intent = new Intent(this, ApgIntentService.class); - - // fill values for this action - Bundle data = new Bundle(); - - boolean useAsciiArmor = true; - long encryptionKeyIds[] = null; - int compressionId = 0; - boolean signOnly = false; - - if (mMode.getCurrentView().getId() == R.id.modeSymmetric) { - Log.d(Constants.TAG, "Symmetric encryption enabled!"); - String passPhrase = mPassPhrase.getText().toString(); - if (passPhrase.length() == 0) { - passPhrase = null; - } - - data.putString(ApgIntentService.SYMMETRIC_PASSPHRASE, passPhrase); - } else { - encryptionKeyIds = mEncryptionKeyIds; - signOnly = (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0); - } - - intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_ENCRYPT_SIGN); - - // choose default settings, target and data bundle by target - if (mContentUri != null) { - data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_STREAM); - data.putParcelable(ApgIntentService.PROVIDER_URI, mContentUri); - - } else if (mEncryptTarget == Id.target.file) { - useAsciiArmor = mAsciiArmour.isChecked(); - compressionId = ((Choice) mFileCompression.getSelectedItem()).getId(); - - data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_FILE); - - Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename=" - + mOutputFilename); - - data.putString(ApgIntentService.INPUT_FILE, mInputFilename); - data.putString(ApgIntentService.OUTPUT_FILE, mOutputFilename); - - } else { - useAsciiArmor = true; - compressionId = Preferences.getPreferences(this).getDefaultMessageCompression(); - - data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_BYTES); - - if (mData != null) { - data.putByteArray(ApgIntentService.MESSAGE_BYTES, mData); - } else { - String message = mMessage.getText().toString(); - if (signOnly && !mReturnResult) { - fixBadCharactersForGmail(message); - } - data.putByteArray(ApgIntentService.MESSAGE_BYTES, message.getBytes()); - } - } - - if (mOverrideAsciiArmour) { - useAsciiArmor = mAsciiArmourDemand; - } - - data.putLong(ApgIntentService.SECRET_KEY_ID, getSecretKeyId()); - data.putBoolean(ApgIntentService.USE_ASCII_AMOR, useAsciiArmor); - data.putLongArray(ApgIntentService.ENCRYPTION_KEYS_IDS, encryptionKeyIds); - data.putInt(ApgIntentService.COMPRESSION_ID, compressionId); - data.putBoolean(ApgIntentService.GENERATE_SIGNATURE, mGenerateSignature); - data.putBoolean(ApgIntentService.SIGN_ONLY, signOnly); - - intent.putExtra(ApgIntentService.EXTRA_DATA, data); - - // Message is received after encrypting is done in ApgService - ApgIntentServiceHandler saveHandler = new ApgIntentServiceHandler(this, - R.string.progress_encrypting, ProgressDialog.STYLE_HORIZONTAL) { - public void handleMessage(Message message) { - // handle messages by standard ApgHandler first - super.handleMessage(message); - - if (message.arg1 == ApgIntentServiceHandler.MESSAGE_OKAY) { - // get returned data bundle - Bundle data = message.getData(); - - String output; - switch (mEncryptTarget) { - case Id.target.clipboard: - output = data.getString(ApgIntentService.RESULT_ENCRYPTED_STRING); - Log.d(Constants.TAG, "output: " + output); - Compatibility.copyToClipboard(EncryptActivity.this, output); - Toast.makeText(EncryptActivity.this, - R.string.encryptionToClipboardSuccessful, Toast.LENGTH_SHORT) - .show(); - break; - - case Id.target.email: - if (mReturnResult) { - Intent intent = new Intent(); - intent.putExtras(data); - setResult(RESULT_OK, intent); - finish(); - return; - } - - output = data.getString(ApgIntentService.RESULT_ENCRYPTED_STRING); - Log.d(Constants.TAG, "output: " + output); - - Intent emailIntent = new Intent(Intent.ACTION_SEND); - emailIntent.setType("text/plain; charset=utf-8"); - emailIntent.putExtra(Intent.EXTRA_TEXT, output); - if (mSubject != null) { - emailIntent.putExtra(Intent.EXTRA_SUBJECT, mSubject); - } - if (mSendTo != null) { - emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] { mSendTo }); - } - startActivity(Intent.createChooser(emailIntent, - getString(R.string.title_sendEmail))); - break; - - case Id.target.file: - Toast.makeText(EncryptActivity.this, R.string.encryptionSuccessful, - Toast.LENGTH_SHORT).show(); - - if (mDeleteAfter.isChecked()) { - // Create and show dialog to delete original file - DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment - .newInstance(mInputFilename); - deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); - } - break; - - default: - // shouldn't happen - break; - - } - } - }; - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(ApgIntentService.EXTRA_MESSENGER, messenger); - - // show progress dialog - saveHandler.showProgressDialog(this); - - // start service with intent - startService(intent); - } - - /** - * Fixes bad message characters for gmail - * - * @param message - * @return - */ - private String fixBadCharactersForGmail(String message) { - // fix the message a bit, trailing spaces and newlines break stuff, - // because GMail sends as HTML and such things fuck up the - // signature, - // TODO: things like "<" and ">" also fuck up the signature - message = message.replaceAll(" +\n", "\n"); - message = message.replaceAll("\n\n+", "\n\n"); - message = message.replaceFirst("^\n+", ""); - // make sure there'll be exactly one newline at the end - message = message.replaceFirst("\n*$", "\n"); - - return message; } private void updateView() { @@ -956,7 +978,7 @@ public class EncryptActivity extends SherlockFragmentActivity { + getResources().getString(R.string.nKeysSelected)); } - if (getSecretKeyId() == Id.key.none) { + if (mSecretKeyId == Id.key.none) { mSign.setChecked(false); mMainUserId.setText(""); mMainUserIdRest.setText(""); @@ -964,7 +986,7 @@ public class EncryptActivity extends SherlockFragmentActivity { String uid = getResources().getString(R.string.unknownUserId); String uidExtra = ""; PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(this, - getSecretKeyId()); + mSecretKeyId); if (keyRing != null) { PGPSecretKey key = PGPHelper.getMasterKey(keyRing); if (key != null) { @@ -987,8 +1009,8 @@ public class EncryptActivity extends SherlockFragmentActivity { private void selectPublicKeys() { Intent intent = new Intent(this, SelectPublicKeyActivity.class); Vector keyIds = new Vector(); - if (getSecretKeyId() != 0) { - keyIds.add(getSecretKeyId()); + if (mSecretKeyId != 0) { + keyIds.add(mSecretKeyId); } if (mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) { for (int i = 0; i < mEncryptionKeyIds.length; ++i) { @@ -1017,7 +1039,7 @@ public class EncryptActivity extends SherlockFragmentActivity { case Id.request.filename: { if (resultCode == RESULT_OK && data != null) { try { - String path = data.getData().getPath(); + String path = FileHelper.getPath(this, data.getData()); Log.d(Constants.TAG, "path=" + path); mFilename.setText(path); @@ -1055,9 +1077,9 @@ public class EncryptActivity extends SherlockFragmentActivity { case Id.request.secret_keys: { if (resultCode == RESULT_OK) { Bundle bundle = data.getExtras(); - setSecretKeyId(bundle.getLong(SelectSecretKeyActivity.RESULT_EXTRA_MASTER_KEY_ID)); + mSecretKeyId = bundle.getLong(SelectSecretKeyActivity.RESULT_EXTRA_MASTER_KEY_ID); } else { - setSecretKeyId(Id.key.none); + mSecretKeyId = Id.key.none; } updateView(); break;