From 56cfb6bc5a5494cb31a3188d6bb4fa53074dbe6a Mon Sep 17 00:00:00 2001 From: Dominik Date: Fri, 16 Nov 2012 16:33:31 +0100 Subject: Rework encrypt for files with intents --- .../thialfihar/android/apg/helper/FileHelper.java | 48 ++ .../org/thialfihar/android/apg/helper/PGPMain.java | 32 +- .../android/apg/service/ApgIntentService.java | 4 +- .../thialfihar/android/apg/ui/DecryptActivity.java | 7 +- .../thialfihar/android/apg/ui/EncryptActivity.java | 496 +++++++++++---------- 5 files changed, 340 insertions(+), 247 deletions(-) (limited to 'org_apg/src/org') 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,180 +204,10 @@ public class EncryptActivity extends SherlockFragmentActivity { // set actionbar without home button if called from another app OtherHelper.setActionBarBackButton(this); - mGenerateSignature = false; - - mSource = (ViewFlipper) findViewById(R.id.source); - mSourceLabel = (TextView) findViewById(R.id.sourceLabel); - mSourcePrevious = (ImageView) findViewById(R.id.sourcePrevious); - mSourceNext = (ImageView) findViewById(R.id.sourceNext); - - mSourcePrevious.setClickable(true); - mSourcePrevious.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_in)); - mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_out)); - mSource.showPrevious(); - updateSource(); - } - }); - - mSourceNext.setClickable(true); - OnClickListener nextSourceClickListener = new OnClickListener() { - public void onClick(View v) { - mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_in)); - mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_out)); - mSource.showNext(); - updateSource(); - } - }; - mSourceNext.setOnClickListener(nextSourceClickListener); - - mSourceLabel.setClickable(true); - mSourceLabel.setOnClickListener(nextSourceClickListener); - - mMode = (ViewFlipper) findViewById(R.id.mode); - mModeLabel = (TextView) findViewById(R.id.modeLabel); - mModePrevious = (ImageView) findViewById(R.id.modePrevious); - mModeNext = (ImageView) findViewById(R.id.modeNext); - - mModePrevious.setClickable(true); - mModePrevious.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_in)); - mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_right_out)); - mMode.showPrevious(); - updateMode(); - } - }); - - OnClickListener nextModeClickListener = new OnClickListener() { - public void onClick(View v) { - mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_in)); - mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, - R.anim.push_left_out)); - mMode.showNext(); - updateMode(); - } - }; - mModeNext.setOnClickListener(nextModeClickListener); - - mModeLabel.setClickable(true); - mModeLabel.setOnClickListener(nextModeClickListener); - - mMessage = (EditText) findViewById(R.id.message); - mSelectKeysButton = (Button) findViewById(R.id.btn_selectEncryptKeys); - mSign = (CheckBox) findViewById(R.id.sign); - mMainUserId = (TextView) findViewById(R.id.mainUserId); - mMainUserIdRest = (TextView) findViewById(R.id.mainUserIdRest); - - mPassPhrase = (EditText) findViewById(R.id.passPhrase); - mPassPhraseAgain = (EditText) findViewById(R.id.passPhraseAgain); - - // measure the height of the source_file view and set the message view's min height to that, - // so it fills mSource fully... bit of a hack. - View tmp = findViewById(R.id.sourceFile); - tmp.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - int height = tmp.getMeasuredHeight(); - mMessage.setMinimumHeight(height); - - mFilename = (EditText) findViewById(R.id.filename); - mBrowse = (ImageButton) findViewById(R.id.btn_browse); - mBrowse.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - FileHelper.openFile(EncryptActivity.this, mFilename.getText().toString(), "*/*", - Id.request.filename); - } - }); - - mFileCompression = (Spinner) findViewById(R.id.fileCompression); - Choice[] choices = new Choice[] { - new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " (" - + getString(R.string.fast) + ")"), - new Choice(Id.choice.compression.zip, "ZIP (" + getString(R.string.fast) + ")"), - new Choice(Id.choice.compression.zlib, "ZLIB (" + getString(R.string.fast) + ")"), - new Choice(Id.choice.compression.bzip2, "BZIP2 (" + getString(R.string.very_slow) - + ")"), }; - ArrayAdapter adapter = new ArrayAdapter(this, - android.R.layout.simple_spinner_item, choices); - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - mFileCompression.setAdapter(adapter); - - int defaultFileCompression = Preferences.getPreferences(this).getDefaultFileCompression(); - for (int i = 0; i < choices.length; ++i) { - if (choices[i].getId() == defaultFileCompression) { - mFileCompression.setSelection(i); - break; - } - } - - mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterEncryption); - - mAsciiArmour = (CheckBox) findViewById(R.id.asciiArmour); - mAsciiArmour.setChecked(Preferences.getPreferences(this).getDefaultAsciiArmour()); - mAsciiArmour.setOnClickListener(new OnClickListener() { - public void onClick(View view) { - guessOutputFilename(); - } - }); + initView(); - mSelectKeysButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - selectPublicKeys(); - } - }); - - mSign.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - CheckBox checkBox = (CheckBox) v; - if (checkBox.isChecked()) { - selectSecretKey(); - } else { - setSecretKeyId(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); - } + // Handle intent actions + handleActions(getIntent()); updateView(); updateSource(); @@ -404,8 +229,8 @@ public class EncryptActivity extends SherlockFragmentActivity { updateActionBarButtons(); if (mReturnResult - && (mMessage.getText().length() > 0 || mData != null || mContentUri != null) - && ((mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) || getSecretKeyId() != 0)) { + && (mMessage.getText().length() > 0 || mData != null) + && ((mEncryptionKeyIds != null && mEncryptionKeyIds.length > 0) || mSecretKeyId != 0)) { encryptClicked(); } } @@ -415,18 +240,41 @@ public class EncryptActivity extends SherlockFragmentActivity { * * @param intent */ - private void handleActionEncryptSign(Intent 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 (ACTION_ENCRYPT_AND_RETURN.equals(action) || ACTION_GENERATE_SIGNATURE.equals(action)) { + 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.equals(action)) { + if (ACTION_GENERATE_SIGNATURE_AND_RETURN.equals(action)) { mGenerateSignature = true; mOverrideAsciiArmour = true; mAsciiArmourDemand = false; @@ -446,27 +294,76 @@ public class EncryptActivity extends SherlockFragmentActivity { 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) { + 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, - signatureKeyId); + preselectedSignatureKeyId); 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()); + mSecretKeyId = masterKey.getKeyID(); } } } } - if (encryptionKeyIds != null) { + if (preselectedEncryptionKeyIds != null) { Vector goodIds = new Vector(); - for (int i = 0; i < encryptionKeyIds.length; ++i) { + for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) { PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, - encryptionKeyIds[i]); + preselectedEncryptionKeyIds[i]); PGPPublicKey masterKey = null; if (keyRing == null) { continue; @@ -488,34 +385,21 @@ public class EncryptActivity extends SherlockFragmentActivity { } } } - - 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); + /** + * 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"); - mOutputFilename = Constants.path.APP_DIR + "/" + file.getName() + ending; + String outputFilename = file.getParent() + File.separator + file.getName() + ending; + + return outputFilename; } private void updateSource() { @@ -583,7 +467,7 @@ public class EncryptActivity extends SherlockFragmentActivity { } } else { if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { - if (getSecretKeyId() == 0) { + if (mSecretKeyId == 0) { setActionbarButtons(false, 0, false, 0); } else { if (mReturnResult) { @@ -651,9 +535,11 @@ public class EncryptActivity extends SherlockFragmentActivity { if (mEncryptTarget == Id.target.file) { String currentFilename = mFilename.getText().toString(); if (mInputFilename == null || !mInputFilename.equals(currentFilename)) { - guessOutputFilename(); + mInputFilename = mFilename.getText().toString(); } + mOutputFilename = guessOutputFilename(mInputFilename); + if (mInputFilename.equals("")) { Toast.makeText(this, R.string.noFileSelected, Toast.LENGTH_SHORT).show(); return; @@ -694,14 +580,14 @@ public class EncryptActivity extends SherlockFragmentActivity { return; } - if (!encryptIt && getSecretKeyId() == 0) { + if (!encryptIt && mSecretKeyId == 0) { Toast.makeText(this, R.string.selectEncryptionOrSignatureKey, Toast.LENGTH_SHORT) .show(); return; } - if (getSecretKeyId() != 0 - && PassphraseCacheService.getCachedPassphrase(this, getSecretKeyId()) == null) { + if (mSecretKeyId != 0 + && PassphraseCacheService.getCachedPassphrase(this, mSecretKeyId) == null) { showPassphraseDialog(); return; @@ -801,9 +687,9 @@ public class EncryptActivity extends SherlockFragmentActivity { intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_ENCRYPT_SIGN); // choose default settings, target and data bundle by target - if (mContentUri != null) { + if (mIntentDataUri != null) { data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_STREAM); - data.putParcelable(ApgIntentService.PROVIDER_URI, mContentUri); + data.putParcelable(ApgIntentService.PROVIDER_URI, mIntentDataUri); } else if (mEncryptTarget == Id.target.file) { useAsciiArmor = mAsciiArmour.isChecked(); @@ -838,7 +724,7 @@ public class EncryptActivity extends SherlockFragmentActivity { useAsciiArmor = mAsciiArmourDemand; } - data.putLong(ApgIntentService.SECRET_KEY_ID, getSecretKeyId()); + 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); @@ -946,6 +832,142 @@ public class EncryptActivity extends SherlockFragmentActivity { return message; } + private void initView() { + mSource = (ViewFlipper) findViewById(R.id.source); + mSourceLabel = (TextView) findViewById(R.id.sourceLabel); + mSourcePrevious = (ImageView) findViewById(R.id.sourcePrevious); + mSourceNext = (ImageView) findViewById(R.id.sourceNext); + + mSourcePrevious.setClickable(true); + mSourcePrevious.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_right_in)); + mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_right_out)); + mSource.showPrevious(); + updateSource(); + } + }); + + mSourceNext.setClickable(true); + OnClickListener nextSourceClickListener = new OnClickListener() { + public void onClick(View v) { + mSource.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_left_in)); + mSource.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_left_out)); + mSource.showNext(); + updateSource(); + } + }; + mSourceNext.setOnClickListener(nextSourceClickListener); + + mSourceLabel.setClickable(true); + mSourceLabel.setOnClickListener(nextSourceClickListener); + + mMode = (ViewFlipper) findViewById(R.id.mode); + mModeLabel = (TextView) findViewById(R.id.modeLabel); + mModePrevious = (ImageView) findViewById(R.id.modePrevious); + mModeNext = (ImageView) findViewById(R.id.modeNext); + + mModePrevious.setClickable(true); + mModePrevious.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_right_in)); + mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_right_out)); + mMode.showPrevious(); + updateMode(); + } + }); + + OnClickListener nextModeClickListener = new OnClickListener() { + public void onClick(View v) { + mMode.setInAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_left_in)); + mMode.setOutAnimation(AnimationUtils.loadAnimation(EncryptActivity.this, + R.anim.push_left_out)); + mMode.showNext(); + updateMode(); + } + }; + mModeNext.setOnClickListener(nextModeClickListener); + + mModeLabel.setClickable(true); + mModeLabel.setOnClickListener(nextModeClickListener); + + mMessage = (EditText) findViewById(R.id.message); + mSelectKeysButton = (Button) findViewById(R.id.btn_selectEncryptKeys); + mSign = (CheckBox) findViewById(R.id.sign); + mMainUserId = (TextView) findViewById(R.id.mainUserId); + mMainUserIdRest = (TextView) findViewById(R.id.mainUserIdRest); + + mPassPhrase = (EditText) findViewById(R.id.passPhrase); + mPassPhraseAgain = (EditText) findViewById(R.id.passPhraseAgain); + + // measure the height of the source_file view and set the message view's min height to that, + // so it fills mSource fully... bit of a hack. + View tmp = findViewById(R.id.sourceFile); + tmp.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); + int height = tmp.getMeasuredHeight(); + mMessage.setMinimumHeight(height); + + mFilename = (EditText) findViewById(R.id.filename); + mBrowse = (ImageButton) findViewById(R.id.btn_browse); + mBrowse.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + FileHelper.openFile(EncryptActivity.this, mFilename.getText().toString(), "*/*", + Id.request.filename); + } + }); + + mFileCompression = (Spinner) findViewById(R.id.fileCompression); + Choice[] choices = new Choice[] { + new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " (" + + getString(R.string.fast) + ")"), + new Choice(Id.choice.compression.zip, "ZIP (" + getString(R.string.fast) + ")"), + new Choice(Id.choice.compression.zlib, "ZLIB (" + getString(R.string.fast) + ")"), + new Choice(Id.choice.compression.bzip2, "BZIP2 (" + getString(R.string.very_slow) + + ")"), }; + ArrayAdapter adapter = new ArrayAdapter(this, + android.R.layout.simple_spinner_item, choices); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + mFileCompression.setAdapter(adapter); + + int defaultFileCompression = Preferences.getPreferences(this).getDefaultFileCompression(); + for (int i = 0; i < choices.length; ++i) { + if (choices[i].getId() == defaultFileCompression) { + mFileCompression.setSelection(i); + break; + } + } + + mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterEncryption); + + mAsciiArmour = (CheckBox) findViewById(R.id.asciiArmour); + mAsciiArmour.setChecked(Preferences.getPreferences(this).getDefaultAsciiArmour()); + + mSelectKeysButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + selectPublicKeys(); + } + }); + + mSign.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + CheckBox checkBox = (CheckBox) v; + if (checkBox.isChecked()) { + selectSecretKey(); + } else { + mSecretKeyId = Id.key.none; + updateView(); + } + } + }); + } + private void updateView() { if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) { mSelectKeysButton.setText(R.string.noKeysSelected); @@ -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; -- cgit v1.2.3