aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik <dominik@dominikschuermann.de>2012-11-16 16:33:31 +0100
committerDominik <dominik@dominikschuermann.de>2012-11-16 16:33:31 +0100
commit56cfb6bc5a5494cb31a3188d6bb4fa53074dbe6a (patch)
tree734f47c37a585b24a01e2101a32d5eee895e091b
parentbbddc4c56dbb71c536aac736d197bcc8e49f6769 (diff)
downloadopen-keychain-56cfb6bc5a5494cb31a3188d6bb4fa53074dbe6a.tar.gz
open-keychain-56cfb6bc5a5494cb31a3188d6bb4fa53074dbe6a.tar.bz2
open-keychain-56cfb6bc5a5494cb31a3188d6bb4fa53074dbe6a.zip
Rework encrypt for files with intents
-rw-r--r--org_apg/AndroidManifest.xml25
-rw-r--r--org_apg/res/values/strings.xml3
-rw-r--r--org_apg/src/org/thialfihar/android/apg/helper/FileHelper.java48
-rw-r--r--org_apg/src/org/thialfihar/android/apg/helper/PGPMain.java32
-rw-r--r--org_apg/src/org/thialfihar/android/apg/service/ApgIntentService.java4
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/DecryptActivity.java7
-rw-r--r--org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java496
7 files changed, 342 insertions, 273 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" />
-
- <!-- DEPRECATED: -->
- <!-- <provider -->
- <!-- android:name=".deprecated.DataProvider" -->
- <!-- android:authorities="org.thialfihar.android.apg.provider" -->
- <!-- android:readPermission="org.thialfihar.android.apg.permission.READ_KEY_DETAILS" /> -->
-
-
- <!-- TODO: need to be moved into new service model -->
- <!-- <service -->
- <!-- android:name=".deprecated.ApgService2" -->
- <!-- android:enabled="true" -->
- <!-- android:exported="true" -->
- <!-- android:permission="org.thialfihar.android.apg.permission.READ_KEY_DETAILS" -->
- <!-- android:process=":remote" > -->
- <!-- <intent-filter> -->
- <!-- <action android:name="org.thialfihar.android.apg.service.IApgService2" /> -->
- <!-- </intent-filter> -->
-
-
- <!-- <meta-data -->
- <!-- android:name="api_version" -->
- <!-- android:value="2" /> -->
- <!-- </service> -->
-
</application>
</manifest> \ 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 @@
<string name="error_wrongPassPhrase">wrong passphrase</string>
<string name="error_savingKeys">error saving some key(s)</string>
<string name="error_couldNotExtractPrivateKey">could not extract private key</string>
-
+ <string name="error_onlyFilesAreSupported">Direct binary data without actual file in filesystem is not supported</string>
+
<!-- progress_lowerCase: lowercase, phrases, usually ending in '…' -->
<string name="progress_done">done.</string>
<string name="progress_initializing">initializing…</string>
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<Choice> adapter = new ArrayAdapter<Choice>(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<PGPSecretKey> signKeys = PGPHelper.getUsableSigningKeys(keyRing);
if (signKeys.size() > 0) {
- setSecretKeyId(masterKey.getKeyID());
+ mSecretKeyId = masterKey.getKeyID();
}
}
}
}
- if (encryptionKeyIds != null) {
+ if (preselectedEncryptionKeyIds != null) {
Vector<Long> goodIds = new Vector<Long>();
- 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<Choice> adapter = new ArrayAdapter<Choice>(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<Long> keyIds = new Vector<Long>();
- 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;