file dialog reworked, file encryption should work again

This commit is contained in:
Dominik 2012-06-18 19:29:23 +03:00
parent cbfbb94300
commit e4489bc78d
11 changed files with 264 additions and 238 deletions

View File

@ -32,6 +32,15 @@ import android.widget.EditText;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.Toast; import android.widget.Toast;
/**
*
*
* SHOUDL BE DELTED, DileDialogFragment is the new implementation
*
*
* @author ds1
*
*/
public class FileDialog { public class FileDialog {
private static EditText mFilename; private static EditText mFilename;
private static ImageButton mBrowse; private static ImageButton mBrowse;

View File

@ -92,8 +92,8 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
public static final String GENERATE_SIGNATURE = "generate_signature"; public static final String GENERATE_SIGNATURE = "generate_signature";
public static final String SIGN_ONLY = "sign_only"; public static final String SIGN_ONLY = "sign_only";
public static final String BYTES = "bytes"; public static final String BYTES = "bytes";
public static final String FILE_URI = "file_uri"; public static final String INPUT_FILE = "input_file";
public static final String OUTPUT_FILENAME = "output_filename"; public static final String OUTPUT_FILE = "output_file";
public static final String PROVIDER_URI = "provider_uri"; public static final String PROVIDER_URI = "provider_uri";
// possible ints for EXTRA_ACTION // possible ints for EXTRA_ACTION
@ -303,8 +303,8 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
long secretKeyId = data.getLong(SECRET_KEY_ID); long secretKeyId = data.getLong(SECRET_KEY_ID);
String passphrase = data.getString(PASSPHRASE); String passphrase = data.getString(PASSPHRASE);
Uri fileUri = Uri.parse(data.getString(FILE_URI)); String inputFile = data.getString(INPUT_FILE);
String outputFilename = data.getString(OUTPUT_FILENAME); String outputFile = data.getString(OUTPUT_FILE);
boolean useAsciiArmour = data.getBoolean(USE_ASCII_AMOR); boolean useAsciiArmour = data.getBoolean(USE_ASCII_AMOR);
long encryptionKeyIds[] = data.getLongArray(ENCRYPTION_KEYS_IDS); long encryptionKeyIds[] = data.getLongArray(ENCRYPTION_KEYS_IDS);
@ -316,26 +316,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
// InputStream // InputStream
long inLength = -1; long inLength = -1;
FileInputStream inStream = null; FileInputStream inStream = null;
if (fileUri.getScheme().equals("file")) { if (inputFile.startsWith(Environment.getExternalStorageDirectory()
// get the rest after "file://"
String path = Uri.decode(fileUri.toString().substring(7));
if (path.startsWith(Environment.getExternalStorageDirectory().getAbsolutePath())) {
if (!Environment.getExternalStorageState()
.equals(Environment.MEDIA_MOUNTED)) {
sendErrorToHandler(new GeneralException(
getString(R.string.error_externalStorageNotReady)));
return;
}
}
inStream = new FileInputStream(path);
File file = new File(path);
inLength = file.length();
}
InputData inputData = new InputData(inStream, inLength);
// OutputStream
if (outputFilename.startsWith(Environment.getExternalStorageDirectory()
.getAbsolutePath())) { .getAbsolutePath())) {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
sendErrorToHandler(new GeneralException( sendErrorToHandler(new GeneralException(
@ -343,7 +324,22 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
return; return;
} }
} }
FileOutputStream outStream = new FileOutputStream(outputFilename); inStream = new FileInputStream(inputFile);
File file = new File(inputFile);
inLength = file.length();
InputData inputData = new InputData(inStream, inLength);
// OutputStream
if (outputFile.startsWith(Environment.getExternalStorageDirectory()
.getAbsolutePath())) {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
sendErrorToHandler(new GeneralException(
getString(R.string.error_externalStorageNotReady)));
return;
}
}
FileOutputStream outStream = new FileOutputStream(outputFile);
// Operation // Operation
if (generateSignature) { if (generateSignature) {
@ -410,7 +406,6 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
FileOutputStream outStream = openFileOutput(streamFilename, Context.MODE_PRIVATE); FileOutputStream outStream = openFileOutput(streamFilename, Context.MODE_PRIVATE);
// Operation // Operation
if (generateSignature) { if (generateSignature) {
Apg.generateSignature(this, inputData, outStream, useAsciiArmour, true, Apg.generateSignature(this, inputData, outStream, useAsciiArmour, true,
secretKeyId, Apg.getCachedPassPhrase(secretKeyId), Preferences secretKeyId, Apg.getCachedPassPhrase(secretKeyId), Preferences

View File

@ -103,7 +103,10 @@ public class BaseActivity extends SherlockFragmentActivity implements Runnable,
switch (item.getItemId()) { switch (item.getItemId()) {
case android.R.id.home: case android.R.id.home:
startActivity(new Intent(this, MainActivity.class)); // app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true; return true;
// TODO: needed?: // TODO: needed?:

View File

@ -29,6 +29,7 @@ import org.thialfihar.android.apg.InputData;
import org.thialfihar.android.apg.PausableThread; import org.thialfihar.android.apg.PausableThread;
import org.thialfihar.android.apg.provider.DataProvider; import org.thialfihar.android.apg.provider.DataProvider;
import org.thialfihar.android.apg.util.Compatibility; import org.thialfihar.android.apg.util.Compatibility;
import org.thialfihar.android.apg.util.Utils;
import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.R;
import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar;
@ -132,6 +133,14 @@ public class DecryptActivity extends BaseActivity {
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
case Id.menu.option.decrypt: { case Id.menu.option.decrypt: {
decryptClicked(); decryptClicked();
@ -204,7 +213,8 @@ public class DecryptActivity extends BaseActivity {
mBrowse = (ImageButton) findViewById(R.id.btn_browse); mBrowse = (ImageButton) findViewById(R.id.btn_browse);
mBrowse.setOnClickListener(new View.OnClickListener() { mBrowse.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
openFile(); Utils.openFile(DecryptActivity.this, mFilename.getText().toString(), "*/*",
Id.request.filename);
} }
}); });
@ -271,7 +281,7 @@ public class DecryptActivity extends BaseActivity {
// replace non breakable spaces // replace non breakable spaces
textData = textData.replaceAll("\\xa0", " "); textData = textData.replaceAll("\\xa0", " ");
mMessage.setText(textData); mMessage.setText(textData);
mDecryptString = getString(R.string.btn_verify); mDecryptString = getString(R.string.btn_verify);
// build new action bar // build new action bar
invalidateOptionsMenu(); invalidateOptionsMenu();
@ -301,11 +311,15 @@ public class DecryptActivity extends BaseActivity {
extras = new Bundle(); extras = new Bundle();
} }
// disable home button on actionbar because this activity is run from another app // set actionbar without home button if called from another app
final ActionBar actionBar = getSupportActionBar(); final ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(true); if (getCallingPackage() != null && getCallingPackage().equals(Apg.PACKAGE_NAME)) {
actionBar.setDisplayHomeAsUpEnabled(false); actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(false); actionBar.setHomeButtonEnabled(true);
} else {
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setHomeButtonEnabled(false);
}
mReturnBinary = extras.getBoolean(Apg.EXTRA_BINARY, false); mReturnBinary = extras.getBoolean(Apg.EXTRA_BINARY, false);
@ -398,23 +412,6 @@ public class DecryptActivity extends BaseActivity {
} }
} }
private void openFile() {
String filename = mFilename.getText().toString();
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setData(Uri.parse("file://" + filename));
intent.setType("*/*");
try {
startActivityForResult(intent, Id.request.filename);
} catch (ActivityNotFoundException e) {
// No compatible file manager was found.
Toast.makeText(this, R.string.noFilemanagerInstalled, Toast.LENGTH_SHORT).show();
}
}
private void guessOutputFilename() { private void guessOutputFilename() {
mInputFilename = mFilename.getText().toString(); mInputFilename = mFilename.getText().toString();
File file = new File(mInputFilename); File file = new File(mInputFilename);

View File

@ -102,7 +102,10 @@ public class EditKeyActivity extends SherlockFragmentActivity {
switch (item.getItemId()) { switch (item.getItemId()) {
case android.R.id.home: case android.R.id.home:
startActivity(new Intent(this, SecretKeyListActivity.class)); // app icon in Action Bar clicked; go home
Intent intent = new Intent(this, SecretKeyListActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true; return true;
case Id.menu.option.save: case Id.menu.option.save:

View File

@ -22,15 +22,16 @@ import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Apg; import org.thialfihar.android.apg.Apg;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.FileDialog;
import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.Preferences; import org.thialfihar.android.apg.Preferences;
import org.thialfihar.android.apg.service.ApgHandler; import org.thialfihar.android.apg.service.ApgHandler;
import org.thialfihar.android.apg.service.ApgService; import org.thialfihar.android.apg.service.ApgService;
import org.thialfihar.android.apg.ui.dialog.FileDialogFragment;
import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment; import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment;
import org.thialfihar.android.apg.ui.dialog.ProgressDialogFragment; import org.thialfihar.android.apg.ui.dialog.ProgressDialogFragment;
import org.thialfihar.android.apg.util.Choice; import org.thialfihar.android.apg.util.Choice;
import org.thialfihar.android.apg.util.Compatibility; import org.thialfihar.android.apg.util.Compatibility;
import org.thialfihar.android.apg.util.Utils;
import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.R;
import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar;
@ -38,9 +39,7 @@ import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
import android.app.Dialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
@ -119,6 +118,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
private long mSecretKeyId = 0; private long mSecretKeyId = 0;
private ProgressDialogFragment mEncryptingDialog; private ProgressDialogFragment mEncryptingDialog;
private FileDialogFragment mFileDialog;
public void setSecretKeyId(long id) { public void setSecretKeyId(long id) {
mSecretKeyId = id; mSecretKeyId = id;
@ -150,6 +150,14 @@ public class EncryptActivity extends SherlockFragmentActivity {
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
case Id.menu.option.encrypt_to_clipboard: { case Id.menu.option.encrypt_to_clipboard: {
Log.d(Constants.TAG, "encrypt_to_clipboard option item clicked!"); Log.d(Constants.TAG, "encrypt_to_clipboard option item clicked!");
encryptToClipboardClicked(); encryptToClipboardClicked();
@ -260,7 +268,8 @@ public class EncryptActivity extends SherlockFragmentActivity {
mBrowse = (ImageButton) findViewById(R.id.btn_browse); mBrowse = (ImageButton) findViewById(R.id.btn_browse);
mBrowse.setOnClickListener(new View.OnClickListener() { mBrowse.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
openFile(); Utils.openFile(EncryptActivity.this, mFilename.getText().toString(), "*/*",
Id.request.filename);
} }
}); });
@ -324,10 +333,14 @@ public class EncryptActivity extends SherlockFragmentActivity {
extras = new Bundle(); extras = new Bundle();
} }
// disable home button on actionbar because this activity is run from another app // set actionbar without home button if called from another app
if (Apg.Intent.ENCRYPT_AND_RETURN.equals(mIntent.getAction())) { final ActionBar actionBar = getSupportActionBar();
final ActionBar actionBar = getSupportActionBar(); Log.d(Constants.TAG, "calling package (only set when using startActivityForResult)="
actionBar.setDisplayShowTitleEnabled(true); + getCallingPackage());
if (getCallingPackage() != null && getCallingPackage().equals(Apg.PACKAGE_NAME)) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
} else {
actionBar.setDisplayHomeAsUpEnabled(false); actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setHomeButtonEnabled(false); actionBar.setHomeButtonEnabled(false);
} }
@ -449,23 +462,6 @@ public class EncryptActivity extends SherlockFragmentActivity {
} }
} }
private void openFile() {
String filename = mFilename.getText().toString();
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setData(Uri.parse("file://" + filename));
intent.setType("*/*");
try {
startActivityForResult(intent, Id.request.filename);
} catch (ActivityNotFoundException e) {
// No compatible file manager was found.
Toast.makeText(this, R.string.noFilemanagerInstalled, Toast.LENGTH_SHORT).show();
}
}
private void guessOutputFilename() { private void guessOutputFilename() {
mInputFilename = mFilename.getText().toString(); mInputFilename = mFilename.getText().toString();
File file = new File(mInputFilename); File file = new File(mInputFilename);
@ -693,7 +689,7 @@ public class EncryptActivity extends SherlockFragmentActivity {
try { try {
PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance( PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(
mSecretKeyId, messenger); messenger, mSecretKeyId);
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
} catch (Apg.GeneralException e) { } catch (Apg.GeneralException e) {
@ -704,7 +700,30 @@ public class EncryptActivity extends SherlockFragmentActivity {
} }
private void askForOutputFilename() { private void askForOutputFilename() {
showDialog(Id.dialog.output_filename); // showDialog(Id.dialog.output_filename);
// Message is received after passphrase is cached
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");
} }
// @Override // @Override
@ -718,9 +737,6 @@ public class EncryptActivity extends SherlockFragmentActivity {
// } // }
private void encryptStart() { private void encryptStart() {
// showDialog(Id.dialog.encrypting);
// startThread();
boolean useAsciiArmour = true; boolean useAsciiArmour = true;
long encryptionKeyIds[] = null; long encryptionKeyIds[] = null;
long signatureKeyId = 0; long signatureKeyId = 0;
@ -758,8 +774,11 @@ public class EncryptActivity extends SherlockFragmentActivity {
intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_ENCRYPT_SIGN_FILE); intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_ENCRYPT_SIGN_FILE);
data.putString(ApgService.FILE_URI, mInputFilename); Log.d(Constants.TAG, "mInputFilename=" + mInputFilename + ", mOutputFilename="
data.putString(ApgService.OUTPUT_FILENAME, mOutputFilename); + mOutputFilename);
data.putString(ApgService.INPUT_FILE, mInputFilename);
data.putString(ApgService.OUTPUT_FILE, mOutputFilename);
} else { } else {
useAsciiArmour = true; useAsciiArmour = true;
@ -961,16 +980,13 @@ public class EncryptActivity extends SherlockFragmentActivity {
switch (requestCode) { switch (requestCode) {
case Id.request.filename: { case Id.request.filename: {
if (resultCode == RESULT_OK && data != null) { if (resultCode == RESULT_OK && data != null) {
String filename = data.getDataString(); try {
if (filename != null) { String path = data.getData().getPath();
// Get rid of URI prefix: Log.d(Constants.TAG, "path=" + path);
if (filename.startsWith("file://")) {
filename = filename.substring(7);
}
// replace %20 and so on
filename = Uri.decode(filename);
mFilename.setText(filename); mFilename.setText(path);
} catch (NullPointerException e) {
Log.e(Constants.TAG, "Nullpointer while retrieving path!");
} }
} }
return; return;
@ -978,16 +994,13 @@ public class EncryptActivity extends SherlockFragmentActivity {
case Id.request.output_filename: { case Id.request.output_filename: {
if (resultCode == RESULT_OK && data != null) { if (resultCode == RESULT_OK && data != null) {
String filename = data.getDataString(); try {
if (filename != null) { String path = data.getData().getPath();
// Get rid of URI prefix: Log.d(Constants.TAG, "path=" + path);
if (filename.startsWith("file://")) {
filename = filename.substring(7);
}
// replace %20 and so on
filename = Uri.decode(filename);
FileDialog.setFilename(filename); mFileDialog.setFilename(path);
} catch (NullPointerException e) {
Log.e(Constants.TAG, "Nullpointer while retrieving path!");
} }
} }
return; return;
@ -1021,32 +1034,32 @@ public class EncryptActivity extends SherlockFragmentActivity {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
} }
@Override // @Override
protected Dialog onCreateDialog(int id) { // protected Dialog onCreateDialog(int id) {
switch (id) { // switch (id) {
case Id.dialog.output_filename: { // case Id.dialog.output_filename: {
return FileDialog.build(this, getString(R.string.title_encryptToFile), // return FileDialog.build(this, getString(R.string.title_encryptToFile),
getString(R.string.specifyFileToEncryptTo), mOutputFilename, // getString(R.string.specifyFileToEncryptTo), mOutputFilename,
new FileDialog.OnClickListener() { // new FileDialog.OnClickListener() {
public void onOkClick(String filename, boolean checked) { // public void onOkClick(String filename, boolean checked) {
removeDialog(Id.dialog.output_filename); // removeDialog(Id.dialog.output_filename);
mOutputFilename = filename; // mOutputFilename = filename;
encryptStart(); // encryptStart();
} // }
//
public void onCancelClick() { // public void onCancelClick() {
removeDialog(Id.dialog.output_filename); // removeDialog(Id.dialog.output_filename);
} // }
}, getString(R.string.filemanager_titleSave), // }, getString(R.string.filemanager_titleSave),
getString(R.string.filemanager_btnSave), null, Id.request.output_filename); // getString(R.string.filemanager_btnSave), null, Id.request.output_filename);
} // }
//
default: { // default: {
break; // break;
} // }
} // }
//
return super.onCreateDialog(id); // return super.onCreateDialog(id);
} // }
} }

View File

@ -49,13 +49,13 @@ public class MainActivity extends SherlockActivity {
public void encryptOnClick(View view) { public void encryptOnClick(View view) {
Intent intent = new Intent(MainActivity.this, EncryptActivity.class); Intent intent = new Intent(MainActivity.this, EncryptActivity.class);
intent.setAction(Apg.Intent.ENCRYPT); intent.setAction(Apg.Intent.ENCRYPT);
startActivity(intent); startActivityForResult(intent, 0); // used instead of startActivity to get callingPackage
} }
public void decryptOnClick(View view) { public void decryptOnClick(View view) {
Intent intent = new Intent(MainActivity.this, DecryptActivity.class); Intent intent = new Intent(MainActivity.this, DecryptActivity.class);
intent.setAction(Apg.Intent.DECRYPT); intent.setAction(Apg.Intent.DECRYPT);
startActivity(intent); startActivityForResult(intent, 0); // used instead of startActivity to get callingPackage
} }
public void scanQrcodeOnClick(View view) { public void scanQrcodeOnClick(View view) {

View File

@ -16,22 +16,15 @@
package org.thialfihar.android.apg.ui.dialog; package org.thialfihar.android.apg.ui.dialog;
import org.spongycastle.openpgp.PGPException;
import org.spongycastle.openpgp.PGPPrivateKey;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.spongycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
import org.thialfihar.android.apg.Apg;
import org.thialfihar.android.apg.Apg.GeneralException;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.Id;
import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.R;
import org.thialfihar.android.apg.util.Utils;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle; import android.os.Bundle;
import android.os.Message; import android.os.Message;
import android.os.Messenger; import android.os.Messenger;
@ -40,64 +33,46 @@ import android.support.v4.app.DialogFragment;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.ImageButton;
import android.widget.Toast;
public class FileDialogFragment extends DialogFragment { public class FileDialogFragment extends DialogFragment {
private Messenger mMessenger; private Messenger mMessenger;
private static final String ARG_MESSENGER = "messenger"; private static final String ARG_MESSENGER = "messenger";
private static final String ARG_SECRET_KEY_ID = "secret_key_id"; private static final String ARG_TITLE = "title";
private static final String ARG_MESSAGE = "message";
private static final String ARG_DEFAULT_FILE = "default_file";
private static final String ARG_CHECKBOX_TEXT = "checkbox_text";
private static final String ARG_REQUEST_CODE = "request_code";
public static final int MESSAGE_OKAY = 1; public static final int MESSAGE_OKAY = 1;
public static final String MESSAGE_DATA_FILENAME = "filename";
public static final String MESSAGE_CHECKED = "checked";
/** /**
* Instantiates new instance of this dialog fragment * Creates new instance of this file dialog fragment
*
*/ */
public static FileDialogFragment newInstance(long secretKeyId, Messenger messenger){ public static FileDialogFragment newInstance(Messenger messenger, String title, String message,
String defaultFile, String checkboxText, int requestCode) {
FileDialogFragment frag = new FileDialogFragment(); FileDialogFragment frag = new FileDialogFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putLong(ARG_SECRET_KEY_ID, secretKeyId);
args.putParcelable(ARG_MESSENGER, messenger); args.putParcelable(ARG_MESSENGER, messenger);
args.putString(ARG_TITLE, title);
args.putString(ARG_MESSAGE, message);
args.putString(ARG_DEFAULT_FILE, defaultFile);
args.putString(ARG_CHECKBOX_TEXT, checkboxText);
args.putInt(ARG_REQUEST_CODE, requestCode);
frag.setArguments(args); frag.setArguments(args);
return frag; return frag;
} }
/**
* Checks if key has a passphrase
*
* @param secretKeyId
* @return true if it has a passphrase
*/
private static boolean hasPassphrase(long secretKeyId) {
// check if the key has no passphrase
try {
PGPSecretKey secretKey = Apg.getMasterKey(Apg.getSecretKeyRing(secretKeyId));
Log.d(Constants.TAG, "Check if key has no passphrase...");
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder().setProvider(
"SC").build("".toCharArray());
PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor);
if (testKey != null) {
Log.d(Constants.TAG, "Key has no passphrase! Caches empty passphrase!");
// cache empty passphrase
Apg.setCachedPassPhrase(secretKey.getKeyID(), "");
return false;
}
} catch (PGPException e) {
// silently catch
}
return true;
}
/** /**
* Creates dialog * Creates dialog
*/ */
@ -105,100 +80,107 @@ public class FileDialogFragment extends DialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
final Activity activity = getActivity(); final Activity activity = getActivity();
long secretKeyId = getArguments().getLong(ARG_SECRET_KEY_ID);
mMessenger = getArguments().getParcelable(ARG_MESSENGER); mMessenger = getArguments().getParcelable(ARG_MESSENGER);
String title = getArguments().getString(ARG_TITLE);
String message = getArguments().getString(ARG_MESSAGE);
String defaultFile = getArguments().getString(ARG_DEFAULT_FILE);
String checkboxText = getArguments().getString(ARG_CHECKBOX_TEXT);
final int requestCode = getArguments().getInt(ARG_REQUEST_CODE);
final EditText mFilename;
final ImageButton mBrowse;
final CheckBox mCheckBox;
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
AlertDialog.Builder alert = new AlertDialog.Builder(activity); AlertDialog.Builder alert = new AlertDialog.Builder(activity);
alert.setTitle(R.string.title_authentication); alert.setTitle(title);
alert.setMessage(message);
final PGPSecretKey secretKey; View view = inflater.inflate(R.layout.file_dialog, null);
if (secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none) { mFilename = (EditText) view.findViewById(R.id.input);
secretKey = null; mFilename.setText(defaultFile);
alert.setMessage(getString(R.string.passPhraseForSymmetricEncryption)); mBrowse = (ImageButton) view.findViewById(R.id.btn_browse);
} else { mBrowse.setOnClickListener(new View.OnClickListener() {
secretKey = Apg.getMasterKey(Apg.getSecretKeyRing(secretKeyId)); public void onClick(View v) {
if (secretKey == null) { // only .asc or .gpg files
alert.setTitle(R.string.title_keyNotFound); Utils.openFile(activity, mFilename.getText().toString(), "text/plain", requestCode);
alert.setMessage(getString(R.string.keyNotFound, secretKeyId));
alert.setPositiveButton(android.R.string.ok, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dismiss();
}
});
alert.setCancelable(false);
return alert.create();
} }
String userId = Apg.getMainUserIdSafe(activity, secretKey); });
alert.setMessage(getString(R.string.passPhraseFor, userId));
mCheckBox = (CheckBox) view.findViewById(R.id.checkbox);
if (checkboxText == null) {
mCheckBox.setEnabled(false);
mCheckBox.setVisibility(View.GONE);
} else {
mCheckBox.setEnabled(true);
mCheckBox.setVisibility(View.VISIBLE);
mCheckBox.setText(checkboxText);
} }
LayoutInflater inflater = activity.getLayoutInflater();
View view = inflater.inflate(R.layout.passphrase, null);
final EditText input = (EditText) view.findViewById(R.id.passphrase_passphrase);
final TextView labelNotUsed = (TextView) view
.findViewById(R.id.passphrase_label_passphrase_again);
labelNotUsed.setVisibility(View.GONE);
final EditText inputNotUsed = (EditText) view
.findViewById(R.id.passphrase_passphrase_again);
inputNotUsed.setVisibility(View.GONE);
alert.setView(view); alert.setView(view);
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dismiss();
String passPhrase = input.getText().toString(); @Override
long keyId; public void onClick(DialogInterface dialog, int id) {
if (secretKey != null) { boolean checked = false;
try { if (mCheckBox.isEnabled()) {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder() checked = mCheckBox.isChecked();
.setProvider("SC").build(passPhrase.toCharArray());
PGPPrivateKey testKey = secretKey.extractPrivateKey(keyDecryptor);
if (testKey == null) {
Toast.makeText(activity, R.string.error_couldNotExtractPrivateKey,
Toast.LENGTH_SHORT).show();
return;
}
} catch (PGPException e) {
Toast.makeText(activity, R.string.wrongPassPhrase, Toast.LENGTH_SHORT)
.show();
return;
}
keyId = secretKey.getKeyID();
} else {
keyId = Id.key.symmetric;
} }
// cache the new passphrase // return resulting data back to activity
Log.d(Constants.TAG, "Everything okay! Caching entered passphrase"); Bundle data = new Bundle();
Apg.setCachedPassPhrase(keyId, passPhrase); data.putString(MESSAGE_DATA_FILENAME, mFilename.getText().toString());
data.putBoolean(MESSAGE_CHECKED, checked);
sendMessageToHandler(MESSAGE_OKAY); sendMessageToHandler(MESSAGE_OKAY, data);
dismiss();
} }
}); });
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
dismiss(); dismiss();
} }
}); });
return alert.create(); return alert.create();
} }
/**
* Updates filename in dialog, normally called in onActivityResult in activity using the
* FileDialog
*
* @param messageId
* @param progress
* @param max
*/
public void setFilename(String filename) {
AlertDialog dialog = (AlertDialog) getDialog();
EditText filenameEditText = (EditText) dialog.findViewById(R.id.input);
if (filenameEditText != null) {
filenameEditText.setText(filename);
}
}
/** /**
* Send message back to handler which is initialized in a activity * Send message back to handler which is initialized in a activity
* *
* @param what * @param what
* Message integer you want to send * Message integer you want to send
*/ */
private void sendMessageToHandler(Integer what) { private void sendMessageToHandler(Integer what, Bundle data) {
Message msg = Message.obtain(); Message msg = Message.obtain();
msg.what = what; msg.what = what;
if (data != null) {
msg.setData(data);
}
try { try {
mMessenger.send(msg); mMessenger.send(msg);

View File

@ -54,7 +54,7 @@ public class PassphraseDialogFragment extends DialogFragment {
public static final int MESSAGE_OKAY = 1; public static final int MESSAGE_OKAY = 1;
/** /**
* Instantiates new instance of this dialog fragment * Creates new instance of this dialog fragment
* *
* @param secretKeyId * @param secretKeyId
* secret key id you want to use * secret key id you want to use
@ -63,7 +63,7 @@ public class PassphraseDialogFragment extends DialogFragment {
* @return * @return
* @throws GeneralException * @throws GeneralException
*/ */
public static PassphraseDialogFragment newInstance(long secretKeyId, Messenger messenger) public static PassphraseDialogFragment newInstance(Messenger messenger, long secretKeyId)
throws GeneralException { throws GeneralException {
// check if secret key has a passphrase // check if secret key has a passphrase
if (!(secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none)) { if (!(secretKeyId == Id.key.symmetric || secretKeyId == Id.key.none)) {

View File

@ -31,7 +31,7 @@ public class ProgressDialogFragment extends DialogFragment {
private static final String ARG_STYLE = "style"; private static final String ARG_STYLE = "style";
/** /**
* Instantiates new instance of this fragment * Creates new instance of this fragment
* *
* @param id * @param id
* @return * @return

View File

@ -29,12 +29,36 @@ import org.spongycastle.openpgp.PGPObjectFactory;
import org.spongycastle.openpgp.PGPSecretKey; import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing; import org.spongycastle.openpgp.PGPSecretKeyRing;
import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Constants;
import org.thialfihar.android.apg.R;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log; import android.util.Log;
import android.widget.Toast;
public class Utils { public class Utils {
/**
* Opens the file manager to select a file to open.
*/
public static void openFile(Activity activity, String filename, String type, int requestCode) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setData(Uri.parse("file://" + filename));
intent.setType(type);
try {
activity.startActivityForResult(intent, requestCode);
} catch (ActivityNotFoundException e) {
// No compatible file manager was found.
Toast.makeText(activity, R.string.noFilemanagerInstalled, Toast.LENGTH_SHORT).show();
}
}
/** /**
* Reads html files from /res/raw/example.html to output them as string. See * Reads html files from /res/raw/example.html to output them as string. See
* http://www.monocube.com/2011/02/08/android-tutorial-html-file-in-webview/ * http://www.monocube.com/2011/02/08/android-tutorial-html-file-in-webview/