diff --git a/res/values/strings.xml b/res/values/strings.xml
index a596a534a..4b7569009 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -242,6 +242,7 @@
finding key...
decompressing data...
verifying integrity...
+ deleting \'%s\' securely...
Read key details from APG.
diff --git a/src/org/thialfihar/android/apg/Apg.java b/src/org/thialfihar/android/apg/Apg.java
index 5983bef1b..725136ef2 100644
--- a/src/org/thialfihar/android/apg/Apg.java
+++ b/src/org/thialfihar/android/apg/Apg.java
@@ -20,10 +20,12 @@ import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
+import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.RandomAccessFile;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPairGenerator;
@@ -1895,4 +1897,24 @@ public class Apg {
}
return size;
}
+
+ static void deleteFileSecurely(Context context, File file, ProgressDialogUpdater progress)
+ throws FileNotFoundException, IOException {
+ long length = file.length();
+ SecureRandom random = new SecureRandom();
+ RandomAccessFile raf = new RandomAccessFile(file, "rws");
+ raf.seek(0);
+ raf.getFilePointer();
+ byte[] data = new byte[1 << 16];
+ int pos = 0;
+ String msg = context.getString(R.string.progress_deletingSecurely, file.getName());
+ while (pos < length) {
+ progress.setProgress(msg, (int)(100 * pos / length), 100);
+ random.nextBytes(data);
+ raf.write(data);
+ pos += data.length;
+ }
+ raf.close();
+ file.delete();
+ }
}
diff --git a/src/org/thialfihar/android/apg/BaseActivity.java b/src/org/thialfihar/android/apg/BaseActivity.java
index 4a0360b25..bea8f1caf 100644
--- a/src/org/thialfihar/android/apg/BaseActivity.java
+++ b/src/org/thialfihar/android/apg/BaseActivity.java
@@ -17,6 +17,8 @@
package org.thialfihar.android.apg;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
import java.util.Locale;
import android.app.Activity;
@@ -44,6 +46,7 @@ public class BaseActivity extends Activity
private ProgressDialog mProgressDialog = null;
private Thread mRunningThread = null;
+ private Thread mDeletingThread = null;
private long mSecretKeyId = 0;
private String mDeleteFile = null;
@@ -149,6 +152,11 @@ public class BaseActivity extends Activity
return mProgressDialog;
}
+ case Id.dialog.deleting: {
+ mProgressDialog.setMessage(this.getString(R.string.progress_initializing));
+ return mProgressDialog;
+ }
+
default: {
break;
}
@@ -235,19 +243,30 @@ public class BaseActivity extends Activity
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
removeDialog(Id.dialog.delete_file);
- File file = new File(getDeleteFile());
- String msg = "";
- if (file.delete()) {
- msg = BaseActivity.this.getString(
- R.string.fileDeleteSuccessful);
- } else {
- msg = BaseActivity.this.getString(
- R.string.errorMessage,
- BaseActivity.this.getString(
- R.string.error_fileDeleteFailed, file));
- }
- Toast.makeText(BaseActivity.this,
- msg, Toast.LENGTH_SHORT).show();
+ final File file = new File(getDeleteFile());
+ showDialog(Id.dialog.deleting);
+ mDeletingThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ Bundle data = new Bundle();
+ data.putInt(Apg.EXTRA_STATUS, Id.message.delete_done);
+ try {
+ Apg.deleteFileSecurely(BaseActivity.this, file, BaseActivity.this);
+ } catch (FileNotFoundException e) {
+ data.putString(Apg.EXTRA_ERROR,
+ BaseActivity.this.getString(
+ R.string.error_fileNotFound, file));
+ } catch (IOException e) {
+ data.putString(Apg.EXTRA_ERROR,
+ BaseActivity.this.getString(
+ R.string.error_fileDeleteFailed, file));
+ }
+ Message msg = new Message();
+ msg.setData(data);
+ sendMessage(msg);
+ }
+ });
+ mDeletingThread.start();
}
});
alert.setNegativeButton(android.R.string.cancel,
@@ -335,8 +354,14 @@ public class BaseActivity extends Activity
break;
}
- case Id.message.import_done: // intentionall no break
- case Id.message.export_done: // intentionall no break
+ case Id.message.delete_done: {
+ mProgressDialog = null;
+ deleteDoneCallback(msg);
+ break;
+ }
+
+ case Id.message.import_done: // intentionally no break
+ case Id.message.export_done: // intentionally no break
case Id.message.done: {
mProgressDialog = null;
doneCallback(msg);
@@ -349,6 +374,22 @@ public class BaseActivity extends Activity
}
+ public void deleteDoneCallback(Message msg) {
+ removeDialog(Id.dialog.deleting);
+ mDeletingThread = null;
+
+ Bundle data = msg.getData();
+ String error = data.getString(Apg.EXTRA_ERROR);
+ String message;
+ if (error != null) {
+ message = getString(R.string.errorMessage, error);
+ } else {
+ message = getString(R.string.fileDeleteSuccessful);
+ }
+
+ Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+ }
+
public void passPhraseCallback(long keyId, String passPhrase) {
Apg.setCachedPassPhrase(keyId, passPhrase);
}
diff --git a/src/org/thialfihar/android/apg/DecryptActivity.java b/src/org/thialfihar/android/apg/DecryptActivity.java
index d8b7ccd9c..f5e35c584 100644
--- a/src/org/thialfihar/android/apg/DecryptActivity.java
+++ b/src/org/thialfihar/android/apg/DecryptActivity.java
@@ -545,8 +545,7 @@ public class DecryptActivity extends BaseActivity {
String error = data.getString(Apg.EXTRA_ERROR);
if (error != null) {
- Toast.makeText(DecryptActivity.this,
- getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show();
+ Toast.makeText(this, getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show();
return;
}
diff --git a/src/org/thialfihar/android/apg/EncryptActivity.java b/src/org/thialfihar/android/apg/EncryptActivity.java
index 4854f355c..5d69d8563 100644
--- a/src/org/thialfihar/android/apg/EncryptActivity.java
+++ b/src/org/thialfihar/android/apg/EncryptActivity.java
@@ -779,8 +779,7 @@ public class EncryptActivity extends BaseActivity {
Bundle data = msg.getData();
String error = data.getString(Apg.EXTRA_ERROR);
if (error != null) {
- Toast.makeText(EncryptActivity.this,
- getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show();
+ Toast.makeText(this, getString(R.string.errorMessage, error), Toast.LENGTH_SHORT).show();
return;
}
switch (mEncryptTarget) {
diff --git a/src/org/thialfihar/android/apg/Id.java b/src/org/thialfihar/android/apg/Id.java
index 9ff484271..73ac39218 100644
--- a/src/org/thialfihar/android/apg/Id.java
+++ b/src/org/thialfihar/android/apg/Id.java
@@ -46,6 +46,7 @@ public final class Id {
public static final int export_done = 0x21070006;
public static final int create_key = 0x21070007;
public static final int edit_key = 0x21070008;
+ public static final int delete_done = 0x21070009;
}
public static final class request {
@@ -74,6 +75,7 @@ public final class Id {
public static final int change_log = 0x21070010;
public static final int output_filename = 0x21070011;
public static final int delete_file = 0x21070012;
+ public static final int deleting = 0x21070013;
}
public static final class task {