mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-12-25 00:18:51 -05:00
externalized import, export, started working on qr code import
This commit is contained in:
parent
5cd51b2ad0
commit
45d760008c
63
org_apg/res/layout/import_from_qr_code.xml
Normal file
63
org_apg/res/layout/import_from_qr_code.xml
Normal file
@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true" >
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/import_from_qr_code_footer"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp" >
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/import_from_qr_code_import"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/import_from_qr_code_import" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/import_from_qr_code_import_sign_and_upload"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/import_from_qr_code_import_sign_and_upload" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/import_from_qr_code_scan_again"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/import_from_qr_code_scan_again" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/import_from_qr_code_finish"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/import_from_qr_code_finish" />
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_above="@id/import_from_qr_code_footer"
|
||||
android:fillViewport="true" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/import_from_qr_code_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="" />
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
</RelativeLayout>
|
@ -34,7 +34,7 @@
|
||||
<string name="title_keyServerPreference">Key Server Preference</string>
|
||||
<string name="title_changePassPhrase">Change Passphrase</string>
|
||||
<string name="title_setPassPhrase">Set Passphrase</string>
|
||||
<string name="title_sendEmail">"Send Mail..."</string>
|
||||
<string name="title_sendEmail">"Send Mail…"</string>
|
||||
<string name="title_encryptToFile">Encrypt To File</string>
|
||||
<string name="title_decryptToFile">Decrypt To File</string>
|
||||
<string name="title_importKeys">Import Keys</string>
|
||||
@ -100,7 +100,7 @@
|
||||
<string name="menu_keyServer">Key Server</string>
|
||||
<string name="menu_updateKey">Update</string>
|
||||
<string name="menu_exportKeyToServer">Export To Server</string>
|
||||
<string name="menu_share">Share with QR Code</string>
|
||||
<string name="menu_share">Share public key with QR Code</string>
|
||||
<string name="menu_scanQRCode">Scan QR Code</string>
|
||||
<string name="menu_signKey">Sign Key</string>
|
||||
|
||||
@ -173,10 +173,10 @@
|
||||
<string name="dsa">DSA</string>
|
||||
<string name="elgamal">ElGamal</string>
|
||||
<string name="rsa">RSA</string>
|
||||
<string name="filemanager_titleOpen">Open...</string>
|
||||
<string name="filemanager_titleSave">Save As...</string>
|
||||
<string name="filemanager_titleEncrypt">Select File To Encrypt...</string>
|
||||
<string name="filemanager_titleDecrypt">Select File To Decrypt...</string>
|
||||
<string name="filemanager_titleOpen">Open…</string>
|
||||
<string name="filemanager_titleSave">Save As…</string>
|
||||
<string name="filemanager_titleEncrypt">Select File To Encrypt…</string>
|
||||
<string name="filemanager_titleDecrypt">Select File To Decrypt…</string>
|
||||
<string name="filemanager_btnOpen">Open</string>
|
||||
<string name="filemanager_btnSave">Save</string>
|
||||
<string name="warning">Warning</string>
|
||||
@ -260,41 +260,41 @@
|
||||
<string name="error_savingKeys">error saving some key(s)</string>
|
||||
<string name="error_couldNotExtractPrivateKey">could not extract private key</string>
|
||||
|
||||
<!-- progress_lowerCase: lowercase, phrases, usually ending in '...' -->
|
||||
<!-- progress_lowerCase: lowercase, phrases, usually ending in '…' -->
|
||||
<string name="progress_done">done.</string>
|
||||
<string name="progress_initializing">initializing...</string>
|
||||
<string name="progress_saving">saving...</string>
|
||||
<string name="progress_importing">importing...</string>
|
||||
<string name="progress_exporting">exporting...</string>
|
||||
<string name="progress_generating">generating key, this can take a while...</string>
|
||||
<string name="progress_buildingKey">building key...</string>
|
||||
<string name="progress_preparingMasterKey">preparing master key...</string>
|
||||
<string name="progress_certifyingMasterKey">certifying master key...</string>
|
||||
<string name="progress_buildingMasterKeyRing">building master key ring...</string>
|
||||
<string name="progress_addingSubKeys">adding sub keys...</string>
|
||||
<string name="progress_savingKeyRing">saving key ring...</string>
|
||||
<string name="progress_importingSecretKeys">importing secret keys...</string>
|
||||
<string name="progress_importingPublicKeys">importing public keys...</string>
|
||||
<string name="progress_reloadingKeys">reloading keys...</string>
|
||||
<string name="progress_exportingKey">exporting key...</string>
|
||||
<string name="progress_exportingKeys">exporting keys...</string>
|
||||
<string name="progress_extractingSignatureKey">extracting signature key...</string>
|
||||
<string name="progress_extractingKey">extracting key...</string>
|
||||
<string name="progress_preparingStreams">preparing streams...</string>
|
||||
<string name="progress_encrypting">encrypting data...</string>
|
||||
<string name="progress_decrypting">decrypting data...</string>
|
||||
<string name="progress_preparingSignature">preparing signature...</string>
|
||||
<string name="progress_generatingSignature">generating signature...</string>
|
||||
<string name="progress_processingSignature">processing signature...</string>
|
||||
<string name="progress_verifyingSignature">verifying signature...</string>
|
||||
<string name="progress_signing">signing...</string>
|
||||
<string name="progress_readingData">reading data...</string>
|
||||
<string name="progress_findingKey">finding key...</string>
|
||||
<string name="progress_decompressingData">decompressing data...</string>
|
||||
<string name="progress_verifyingIntegrity">verifying integrity...</string>
|
||||
<string name="progress_deletingSecurely">deleting \'%s\' securely...</string>
|
||||
<string name="progress_querying">querying...</string>
|
||||
<string name="progress_queryingServer">querying %s...</string>
|
||||
<string name="progress_initializing">initializing…</string>
|
||||
<string name="progress_saving">saving…</string>
|
||||
<string name="progress_importing">importing…</string>
|
||||
<string name="progress_exporting">exporting…</string>
|
||||
<string name="progress_generating">generating key, this can take a while…</string>
|
||||
<string name="progress_buildingKey">building key…</string>
|
||||
<string name="progress_preparingMasterKey">preparing master key…</string>
|
||||
<string name="progress_certifyingMasterKey">certifying master key…</string>
|
||||
<string name="progress_buildingMasterKeyRing">building master key ring…</string>
|
||||
<string name="progress_addingSubKeys">adding sub keys…</string>
|
||||
<string name="progress_savingKeyRing">saving key ring…</string>
|
||||
<string name="progress_importingSecretKeys">importing secret keys…</string>
|
||||
<string name="progress_importingPublicKeys">importing public keys…</string>
|
||||
<string name="progress_reloadingKeys">reloading keys…</string>
|
||||
<string name="progress_exportingKey">exporting key…</string>
|
||||
<string name="progress_exportingKeys">exporting keys…</string>
|
||||
<string name="progress_extractingSignatureKey">extracting signature key…</string>
|
||||
<string name="progress_extractingKey">extracting key…</string>
|
||||
<string name="progress_preparingStreams">preparing streams…</string>
|
||||
<string name="progress_encrypting">encrypting data…</string>
|
||||
<string name="progress_decrypting">decrypting data…</string>
|
||||
<string name="progress_preparingSignature">preparing signature…</string>
|
||||
<string name="progress_generatingSignature">generating signature…</string>
|
||||
<string name="progress_processingSignature">processing signature…</string>
|
||||
<string name="progress_verifyingSignature">verifying signature…</string>
|
||||
<string name="progress_signing">signing…</string>
|
||||
<string name="progress_readingData">reading data…</string>
|
||||
<string name="progress_findingKey">finding key…</string>
|
||||
<string name="progress_decompressingData">decompressing data…</string>
|
||||
<string name="progress_verifyingIntegrity">verifying integrity…</string>
|
||||
<string name="progress_deletingSecurely">deleting \'%s\' securely…</string>
|
||||
<string name="progress_querying">querying…</string>
|
||||
<string name="progress_queryingServer">querying %s…</string>
|
||||
|
||||
<!-- permission strings -->
|
||||
<string name="permission_read_key_details_label">Read key details from APG.</string>
|
||||
@ -316,7 +316,7 @@
|
||||
<string name="slow">slow</string>
|
||||
<string name="very_slow">very slow</string>
|
||||
|
||||
<!-- APG Fork -->
|
||||
<!-- APG 2.0 -->
|
||||
|
||||
|
||||
<!-- Dashboard -->
|
||||
@ -333,4 +333,11 @@
|
||||
<string name="help_tab_about">About</string>
|
||||
<string name="help_about_version">Version:</string>
|
||||
|
||||
<!-- Import from QR Code -->
|
||||
|
||||
<string name="import_from_qr_code_import">Import key (only locally)</string>
|
||||
<string name="import_from_qr_code_import_sign_and_upload">Import, Sign, and upload key</string>
|
||||
<string name="import_from_qr_code_scan_again">Scan qr code again</string>
|
||||
<string name="import_from_qr_code_finish">Finish</string>
|
||||
|
||||
</resources>
|
@ -16,6 +16,9 @@
|
||||
|
||||
package org.thialfihar.android.apg;
|
||||
|
||||
import java.security.Security;
|
||||
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.thialfihar.android.apg.helper.PGPMain;
|
||||
import org.thialfihar.android.apg.service.PassphraseCacheService;
|
||||
|
||||
@ -23,6 +26,10 @@ import android.app.Application;
|
||||
|
||||
public class ApgApplication extends Application {
|
||||
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
@ -35,7 +35,7 @@ public final class Id {
|
||||
public static final int edit = 0x21070003;
|
||||
public static final int update = 0x21070004;
|
||||
public static final int exportToServer = 0x21070005;
|
||||
public static final int share = 0x21070006;
|
||||
public static final int share_qr_code = 0x21070006;
|
||||
public static final int signKey = 0x21070007;
|
||||
|
||||
public static final class option {
|
||||
|
@ -86,22 +86,26 @@ public class OtherHelper {
|
||||
*/
|
||||
public static void logDebugBundle(Bundle bundle, String bundleName) {
|
||||
if (Constants.DEBUG) {
|
||||
Set<String> ks = bundle.keySet();
|
||||
Iterator<String> iterator = ks.iterator();
|
||||
if (bundle != null) {
|
||||
Set<String> ks = bundle.keySet();
|
||||
Iterator<String> iterator = ks.iterator();
|
||||
|
||||
Log.d(Constants.TAG, "Bundle " + bundleName + ":");
|
||||
Log.d(Constants.TAG, "------------------------------");
|
||||
while (iterator.hasNext()) {
|
||||
String key = iterator.next();
|
||||
Object value = bundle.get(key);
|
||||
Log.d(Constants.TAG, "Bundle " + bundleName + ":");
|
||||
Log.d(Constants.TAG, "------------------------------");
|
||||
while (iterator.hasNext()) {
|
||||
String key = iterator.next();
|
||||
Object value = bundle.get(key);
|
||||
|
||||
if (value != null) {
|
||||
Log.d(Constants.TAG, key + " : " + value.toString());
|
||||
} else {
|
||||
Log.d(Constants.TAG, key + " : null");
|
||||
if (value != null) {
|
||||
Log.d(Constants.TAG, key + " : " + value.toString());
|
||||
} else {
|
||||
Log.d(Constants.TAG, key + " : null");
|
||||
}
|
||||
}
|
||||
Log.d(Constants.TAG, "------------------------------");
|
||||
} else {
|
||||
Log.d(Constants.TAG, "Bundle " + bundleName + ": null");
|
||||
}
|
||||
Log.d(Constants.TAG, "------------------------------");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package org.thialfihar.android.apg.helper;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Calendar;
|
||||
@ -24,6 +25,7 @@ import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||
import org.spongycastle.bcpg.sig.KeyFlags;
|
||||
import org.spongycastle.openpgp.PGPKeyRing;
|
||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||
@ -34,8 +36,10 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSignature;
|
||||
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
||||
import org.spongycastle.openpgp.PGPUtil;
|
||||
import org.thialfihar.android.apg.Constants;
|
||||
import org.thialfihar.android.apg.R;
|
||||
import org.thialfihar.android.apg.util.IterableIterator;
|
||||
import org.thialfihar.android.apg.util.Log;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
@ -186,7 +190,7 @@ public class PGPHelper {
|
||||
}
|
||||
|
||||
public static PGPPublicKey getEncryptPublicKey(long masterKeyId) {
|
||||
//TODO: externalize getSecretKeyRing from PGPWrapper into a DatabaseHelper
|
||||
// TODO: externalize getSecretKeyRing from PGPWrapper into a DatabaseHelper
|
||||
PGPPublicKeyRing keyRing = PGPMain.getPublicKeyRing(masterKeyId);
|
||||
if (keyRing == null) {
|
||||
return null;
|
||||
@ -199,7 +203,7 @@ public class PGPHelper {
|
||||
}
|
||||
|
||||
public static PGPSecretKey getSigningKey(long masterKeyId) {
|
||||
//TODO: externalize getSecretKeyRing from PGPWrapper into a DatabaseHelper
|
||||
// TODO: externalize getSecretKeyRing from PGPWrapper into a DatabaseHelper
|
||||
PGPSecretKeyRing keyRing = PGPMain.getSecretKeyRing(masterKeyId);
|
||||
if (keyRing == null) {
|
||||
return null;
|
||||
@ -380,12 +384,42 @@ public class PGPHelper {
|
||||
|
||||
}
|
||||
|
||||
public static String getPubkeyAsArmoredString(long keyId) {
|
||||
PGPPublicKey key = PGPMain.getPublicKey(keyId);
|
||||
// if it is no public key get it from your own keys...
|
||||
if (key == null) {
|
||||
PGPSecretKey secretKey = PGPMain.getSecretKey(keyId);
|
||||
if (secretKey == null) {
|
||||
Log.e(Constants.TAG, "Key could not be found!");
|
||||
return null;
|
||||
}
|
||||
key = secretKey.getPublicKey();
|
||||
}
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ArmoredOutputStream aos = new ArmoredOutputStream(bos);
|
||||
String armouredKey = null;
|
||||
try {
|
||||
aos.write(key.getEncoded());
|
||||
aos.close();
|
||||
|
||||
armouredKey = bos.toString("UTF-8");
|
||||
} catch (IOException e) {
|
||||
Log.e(Constants.TAG, "Problems while encoding key as armored string", e);
|
||||
}
|
||||
|
||||
Log.d(Constants.TAG, "key:" + armouredKey);
|
||||
|
||||
return armouredKey;
|
||||
}
|
||||
|
||||
public static String getFingerPrint(long keyId) {
|
||||
PGPPublicKey key = PGPMain.getPublicKey(keyId);
|
||||
if (key == null) {
|
||||
PGPSecretKey secretKey = PGPMain.getSecretKey(keyId);
|
||||
if (secretKey == null) {
|
||||
return "";
|
||||
Log.e(Constants.TAG, "Key could not be found!");
|
||||
return null;
|
||||
}
|
||||
key = secretKey.getPublicKey();
|
||||
}
|
||||
|
@ -662,7 +662,7 @@ public class PGPMain {
|
||||
}
|
||||
}
|
||||
|
||||
public static Bundle importKeyRings(Activity context, int type, InputData data,
|
||||
public static Bundle importKeyRings(Context context, int type, InputData data,
|
||||
ProgressDialogUpdater progress) throws GeneralException, FileNotFoundException,
|
||||
PGPException, IOException {
|
||||
Bundle returnData = new Bundle();
|
||||
@ -733,7 +733,7 @@ public class PGPMain {
|
||||
return returnData;
|
||||
}
|
||||
|
||||
public static Bundle exportKeyRings(Activity context, Vector<Integer> keyRingIds,
|
||||
public static Bundle exportKeyRings(Context context, Vector<Integer> keyRingIds,
|
||||
OutputStream outStream, ProgressDialogUpdater progress) throws GeneralException,
|
||||
FileNotFoundException, PGPException, IOException {
|
||||
Bundle returnData = new Bundle();
|
||||
|
@ -26,6 +26,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.spongycastle.openpgp.PGPSecretKey;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
@ -66,7 +67,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
|
||||
|
||||
/* keys for data bundle */
|
||||
|
||||
// encrypt and decrypt
|
||||
// encrypt, decrypt, import export
|
||||
public static final String TARGET = "target";
|
||||
// possible targets:
|
||||
public static final int TARGET_BYTES = 1;
|
||||
@ -91,7 +92,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
|
||||
public static final String RETURN_BYTES = "returnBinary";
|
||||
public static final String CIPHERTEXT_BYTES = "ciphertextBytes";
|
||||
public static final String ASSUME_SYMMETRIC = "assumeSymmetric";
|
||||
public static final String LOOKUP_UNKNOWN_KEY = "lookup_unknown_key";
|
||||
public static final String LOOKUP_UNKNOWN_KEY = "lookupUnknownKey";
|
||||
|
||||
// edit keys
|
||||
public static final String NEW_PASSPHRASE = "newPassphrase";
|
||||
@ -103,13 +104,26 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
|
||||
|
||||
// generate key
|
||||
public static final String ALGORITHM = "algorithm";
|
||||
public static final String KEY_SIZE = "key_size";
|
||||
public static final String KEY_SIZE = "keySize";
|
||||
public static final String SYMMETRIC_PASSPHRASE = "passphrase";
|
||||
public static final String MASTER_KEY = "masterKey";
|
||||
|
||||
// delete file securely
|
||||
public static final String DELETE_FILE = "deleteFile";
|
||||
|
||||
// import key
|
||||
public static final String IMPORT_INPUT_STREAM = "importInputStream";
|
||||
public static final String IMPORT_FILENAME = "importFilename";
|
||||
public static final String IMPORT_BYTES = "importBytes";
|
||||
public static final String IMPORT_KEY_TYPE = "importKeyType";
|
||||
|
||||
// export key
|
||||
public static final String EXPORT_OUTPUT_STREAM = "exportOutputStream";
|
||||
public static final String EXPORT_FILENAME = "exportFilename";
|
||||
public static final String EXPORT_KEY_TYPE = "exportKeyType";
|
||||
public static final String EXPORT_ALL = "exportAll";
|
||||
public static final String EXPORT_KEY_RING_ID = "exportKeyRingId";
|
||||
|
||||
/* possible EXTRA_ACTIONs */
|
||||
public static final int ACTION_ENCRYPT_SIGN = 10;
|
||||
|
||||
@ -121,6 +135,9 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
|
||||
|
||||
public static final int ACTION_DELETE_FILE_SECURELY = 40;
|
||||
|
||||
public static final int ACTION_IMPORT_KEY = 50;
|
||||
public static final int ACTION_EXPORT_KEY = 51;
|
||||
|
||||
/* possible data keys as result send over messenger */
|
||||
// keys
|
||||
public static final String RESULT_NEW_KEY = "newKey";
|
||||
@ -580,6 +597,104 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
|
||||
|
||||
break;
|
||||
|
||||
case ACTION_IMPORT_KEY:
|
||||
try {
|
||||
|
||||
/* Input */
|
||||
int target = data.getInt(TARGET);
|
||||
|
||||
int keyType = Id.type.public_key;
|
||||
if (data.containsKey(IMPORT_KEY_TYPE)) {
|
||||
keyType = data.getInt(IMPORT_KEY_TYPE);
|
||||
}
|
||||
|
||||
/* Operation */
|
||||
InputStream inStream = null;
|
||||
long inLength = -1;
|
||||
InputData inputData = null;
|
||||
switch (target) {
|
||||
case TARGET_BYTES: /* import key from bytes directly */
|
||||
byte[] bytes = data.getByteArray(IMPORT_BYTES);
|
||||
|
||||
inStream = new ByteArrayInputStream(bytes);
|
||||
inLength = bytes.length;
|
||||
|
||||
inputData = new InputData(inStream, inLength);
|
||||
|
||||
break;
|
||||
case TARGET_FILE: /* import key from file */
|
||||
String inputFile = data.getString(IMPORT_FILENAME);
|
||||
|
||||
inStream = new FileInputStream(inputFile);
|
||||
File file = new File(inputFile);
|
||||
inLength = file.length();
|
||||
inputData = new InputData(inStream, inLength);
|
||||
|
||||
break;
|
||||
|
||||
case TARGET_STREAM:
|
||||
// TODO: not implemented
|
||||
break;
|
||||
}
|
||||
|
||||
Bundle resultData = new Bundle();
|
||||
resultData = PGPMain.importKeyRings(this, keyType, inputData, this);
|
||||
|
||||
sendMessageToHandler(ApgHandler.MESSAGE_OKAY, resultData);
|
||||
} catch (Exception e) {
|
||||
sendErrorToHandler(e);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ACTION_EXPORT_KEY:
|
||||
try {
|
||||
|
||||
/* Input */
|
||||
int keyType = Id.type.public_key;
|
||||
if (data.containsKey(EXPORT_KEY_TYPE)) {
|
||||
keyType = data.getInt(EXPORT_KEY_TYPE);
|
||||
}
|
||||
|
||||
String outputFile = data.getString(EXPORT_FILENAME);
|
||||
|
||||
boolean exportAll = data.getBoolean(EXPORT_ALL);
|
||||
int keyRingId = -1;
|
||||
if (!exportAll) {
|
||||
keyRingId = data.getInt(EXPORT_KEY_RING_ID);
|
||||
}
|
||||
|
||||
/* Operation */
|
||||
|
||||
// check if storage is ready
|
||||
if (!FileHelper.isStorageMounted(outputFile)) {
|
||||
sendErrorToHandler(new GeneralException(
|
||||
getString(R.string.error_externalStorageNotReady)));
|
||||
return;
|
||||
}
|
||||
|
||||
// OutputStream
|
||||
FileOutputStream outStream = new FileOutputStream(outputFile);
|
||||
|
||||
Vector<Integer> keyRingIds = new Vector<Integer>();
|
||||
if (exportAll) {
|
||||
keyRingIds = PGPMain
|
||||
.getKeyRingIds(keyType == Id.type.public_key ? Id.database.type_public
|
||||
: Id.database.type_secret);
|
||||
} else {
|
||||
keyRingIds.add(keyRingId);
|
||||
}
|
||||
|
||||
Bundle resultData = new Bundle();
|
||||
resultData = PGPMain.exportKeyRings(this, keyRingIds, outStream, this);
|
||||
|
||||
sendMessageToHandler(ApgHandler.MESSAGE_OKAY, resultData);
|
||||
} catch (Exception e) {
|
||||
sendErrorToHandler(e);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -693,7 +693,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
||||
private void decryptStart() {
|
||||
Log.d(Constants.TAG, "decryptStart");
|
||||
|
||||
// Send all information needed to service to edit key in other thread
|
||||
// Send all information needed to service to decrypt in other thread
|
||||
Intent intent = new Intent(this, ApgService.class);
|
||||
|
||||
// fill values for this action
|
||||
|
@ -33,6 +33,8 @@ import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import org.thialfihar.android.apg.util.Log;
|
||||
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
@ -61,86 +63,98 @@ public class ImportFromQRCodeActivity extends BaseActivity {
|
||||
new IntentIntegrator(this).initiateScan();
|
||||
}
|
||||
|
||||
// private void importAndSignOld(final long keyId, final String expectedFingerprint) {
|
||||
// if (expectedFingerprint != null && expectedFingerprint.length() > 0) {
|
||||
//
|
||||
// Thread t = new Thread() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// try {
|
||||
// // TODO: display some sort of spinner here while the user waits
|
||||
//
|
||||
// // TODO: there should be only 1
|
||||
// HkpKeyServer server = new HkpKeyServer(mPreferences.getKeyServers()[0]);
|
||||
// String encodedKey = server.get(keyId);
|
||||
//
|
||||
// PGPKeyRing keyring = PGPHelper.decodeKeyRing(new ByteArrayInputStream(
|
||||
// encodedKey.getBytes()));
|
||||
// if (keyring != null && keyring instanceof PGPPublicKeyRing) {
|
||||
// PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring;
|
||||
//
|
||||
// // make sure the fingerprints match before we cache this thing
|
||||
// String actualFingerprint = PGPHelper.convertToHex(publicKeyRing
|
||||
// .getPublicKey().getFingerprint());
|
||||
// if (expectedFingerprint.equals(actualFingerprint)) {
|
||||
// // store the signed key in our local cache
|
||||
// int retval = PGPMain.storeKeyRingInCache(publicKeyRing);
|
||||
// if (retval != Id.return_value.ok
|
||||
// && retval != Id.return_value.updated) {
|
||||
// status.putString(EXTRA_ERROR,
|
||||
// "Failed to store signed key in local cache");
|
||||
// } else {
|
||||
// Intent intent = new Intent(ImportFromQRCodeActivity.this,
|
||||
// SignKeyActivity.class);
|
||||
// intent.putExtra(EXTRA_KEY_ID, keyId);
|
||||
// startActivityForResult(intent, Id.request.sign_key);
|
||||
// }
|
||||
// } else {
|
||||
// status.putString(
|
||||
// EXTRA_ERROR,
|
||||
// "Scanned fingerprint does NOT match the fingerprint of the received key. You shouldnt trust this key.");
|
||||
// }
|
||||
// }
|
||||
// } catch (QueryException e) {
|
||||
// Log.e(TAG, "Failed to query KeyServer", e);
|
||||
// status.putString(EXTRA_ERROR, "Failed to query KeyServer");
|
||||
// status.putInt(Constants.extras.STATUS, Id.message.done);
|
||||
// } catch (IOException e) {
|
||||
// Log.e(TAG, "Failed to query KeyServer", e);
|
||||
// status.putString(EXTRA_ERROR, "Failed to query KeyServer");
|
||||
// status.putInt(Constants.extras.STATUS, Id.message.done);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// t.setName("KeyExchange Download Thread");
|
||||
// t.setDaemon(true);
|
||||
// t.start();
|
||||
// }
|
||||
// }
|
||||
|
||||
private void importAndSign(final long keyId, final String expectedFingerprint) {
|
||||
if (expectedFingerprint != null && expectedFingerprint.length() > 0) {
|
||||
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// TODO: display some sort of spinner here while the user waits
|
||||
// setContentView(R.layout.import_from_qr_code);
|
||||
|
||||
// TODO: there should be only 1
|
||||
HkpKeyServer server = new HkpKeyServer(mPreferences.getKeyServers()[0]);
|
||||
String encodedKey = server.get(keyId);
|
||||
|
||||
PGPKeyRing keyring = PGPHelper.decodeKeyRing(new ByteArrayInputStream(
|
||||
encodedKey.getBytes()));
|
||||
if (keyring != null && keyring instanceof PGPPublicKeyRing) {
|
||||
PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring;
|
||||
|
||||
// make sure the fingerprints match before we cache this thing
|
||||
String actualFingerprint = PGPHelper.convertToHex(publicKeyRing
|
||||
.getPublicKey().getFingerprint());
|
||||
if (expectedFingerprint.equals(actualFingerprint)) {
|
||||
// store the signed key in our local cache
|
||||
int retval = PGPMain.storeKeyRingInCache(publicKeyRing);
|
||||
if (retval != Id.return_value.ok
|
||||
&& retval != Id.return_value.updated) {
|
||||
status.putString(EXTRA_ERROR,
|
||||
"Failed to store signed key in local cache");
|
||||
} else {
|
||||
Intent intent = new Intent(ImportFromQRCodeActivity.this,
|
||||
SignKeyActivity.class);
|
||||
intent.putExtra(EXTRA_KEY_ID, keyId);
|
||||
startActivityForResult(intent, Id.request.sign_key);
|
||||
}
|
||||
} else {
|
||||
status.putString(
|
||||
EXTRA_ERROR,
|
||||
"Scanned fingerprint does NOT match the fingerprint of the received key. You shouldnt trust this key.");
|
||||
}
|
||||
}
|
||||
} catch (QueryException e) {
|
||||
Log.e(TAG, "Failed to query KeyServer", e);
|
||||
status.putString(EXTRA_ERROR, "Failed to query KeyServer");
|
||||
status.putInt(Constants.extras.STATUS, Id.message.done);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to query KeyServer", e);
|
||||
status.putString(EXTRA_ERROR, "Failed to query KeyServer");
|
||||
status.putInt(Constants.extras.STATUS, Id.message.done);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
t.setName("KeyExchange Download Thread");
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
switch (requestCode) {
|
||||
case IntentIntegrator.REQUEST_CODE: {
|
||||
boolean debug = true; // TODO: remove this!!!
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode,
|
||||
data);
|
||||
if (debug || (scanResult != null && scanResult.getFormatName() != null)) {
|
||||
String[] bits = debug ? new String[] { "5993515643896327656",
|
||||
"0816 F68A 6816 68FB 01BF 2CA5 532D 3EB9 1E2F EDE8" } : scanResult
|
||||
.getContents().split(",");
|
||||
if (bits.length != 2) {
|
||||
return; // dont know how to handle this. Not a valid code
|
||||
}
|
||||
if (scanResult != null && scanResult.getFormatName() != null) {
|
||||
|
||||
long keyId = Long.parseLong(bits[0]);
|
||||
String expectedFingerprint = bits[1];
|
||||
// show layout
|
||||
setContentView(R.layout.import_from_qr_code);
|
||||
TextView contentView = (TextView) findViewById(R.id.import_from_qr_code_content);
|
||||
|
||||
importAndSign(keyId, expectedFingerprint);
|
||||
String content = scanResult.getContents();
|
||||
|
||||
contentView.setText(content);
|
||||
// String[] bits = scanResult.getContents().split(",");
|
||||
// if (bits.length != 2) {
|
||||
// return; // dont know how to handle this. Not a valid code
|
||||
// }
|
||||
//
|
||||
// long keyId = Long.parseLong(bits[0]);
|
||||
// String expectedFingerprint = bits[1];
|
||||
|
||||
// importAndSign(keyId, expectedFingerprint);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Id.request.sign_key: {
|
||||
|
@ -16,9 +16,6 @@
|
||||
|
||||
package org.thialfihar.android.apg.ui;
|
||||
|
||||
import org.spongycastle.openpgp.PGPException;
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.thialfihar.android.apg.Constants;
|
||||
import org.thialfihar.android.apg.Id;
|
||||
import org.thialfihar.android.apg.helper.PGPHelper;
|
||||
@ -26,14 +23,19 @@ import org.thialfihar.android.apg.helper.PGPMain;
|
||||
import org.thialfihar.android.apg.provider.KeyRings;
|
||||
import org.thialfihar.android.apg.provider.Keys;
|
||||
import org.thialfihar.android.apg.provider.UserIds;
|
||||
import org.thialfihar.android.apg.service.ApgHandler;
|
||||
import org.thialfihar.android.apg.service.ApgService;
|
||||
import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment;
|
||||
import org.thialfihar.android.apg.ui.dialog.DeleteKeyDialogFragment;
|
||||
import org.thialfihar.android.apg.ui.dialog.FileDialogFragment;
|
||||
import org.thialfihar.android.apg.util.InputData;
|
||||
import org.thialfihar.android.apg.ui.dialog.ProgressDialogFragment;
|
||||
import org.thialfihar.android.apg.R;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||
import com.actionbarsherlock.view.MenuItem;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.app.SearchManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@ -59,25 +61,14 @@ import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Vector;
|
||||
|
||||
public class KeyListActivity extends BaseActivity {
|
||||
public class KeyListActivity extends SherlockFragmentActivity {
|
||||
|
||||
public static final String ACTION_IMPORT = Constants.INTENT_PREFIX + "IMPORT";
|
||||
|
||||
public static final String EXTRA_TEXT = "text";
|
||||
|
||||
// TODO: remove when using new intentservice:
|
||||
public static final String EXTRA_ERROR = "error";
|
||||
|
||||
protected ExpandableListView mList;
|
||||
protected KeyListAdapter mListAdapter;
|
||||
protected View mFilterLayout;
|
||||
@ -251,7 +242,7 @@ public class KeyListActivity extends BaseActivity {
|
||||
|
||||
case Id.menu.delete: {
|
||||
mSelectedItem = groupPosition;
|
||||
showDialog(Id.dialog.delete_key);
|
||||
showDeleteKeyDialog();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -261,177 +252,87 @@ public class KeyListActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
private void showDeleteKeyDialog() {
|
||||
final int keyRingId = mListAdapter.getKeyRingId(mSelectedItem);
|
||||
mSelectedItem = -1;
|
||||
|
||||
switch (id) {
|
||||
case Id.dialog.delete_key: {
|
||||
final int keyRingId = mListAdapter.getKeyRingId(mSelectedItem);
|
||||
mSelectedItem = -1;
|
||||
// TODO: better way to do this?
|
||||
String userId = "<unknown>";
|
||||
Object keyRing = PGPMain.getKeyRing(keyRingId);
|
||||
if (keyRing != null) {
|
||||
if (keyRing instanceof PGPPublicKeyRing) {
|
||||
userId = PGPHelper.getMainUserIdSafe(this,
|
||||
PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing));
|
||||
} else {
|
||||
userId = PGPHelper.getMainUserIdSafe(this,
|
||||
PGPHelper.getMasterKey((PGPSecretKeyRing) keyRing));
|
||||
// Message is received after key is deleted
|
||||
Handler returnHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
|
||||
refreshList();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.warning);
|
||||
builder.setMessage(getString(
|
||||
mKeyType == Id.type.public_key ? R.string.keyDeletionConfirmation
|
||||
: R.string.secretKeyDeletionConfirmation, userId));
|
||||
builder.setIcon(android.R.drawable.ic_dialog_alert);
|
||||
builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
deleteKey(keyRingId);
|
||||
removeDialog(Id.dialog.delete_key);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(android.R.string.cancel,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
removeDialog(Id.dialog.delete_key);
|
||||
}
|
||||
});
|
||||
return builder.create();
|
||||
}
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(returnHandler);
|
||||
|
||||
default: {
|
||||
return super.onCreateDialog(id);
|
||||
}
|
||||
}
|
||||
DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
|
||||
keyRingId, mKeyType);
|
||||
|
||||
deleteKeyDialog.show(getSupportFragmentManager(), "deleteKeyDialog");
|
||||
}
|
||||
|
||||
public void importKeys() {
|
||||
showDialog(Id.dialog.importing);
|
||||
mTask = Id.task.import_keys;
|
||||
startThread();
|
||||
}
|
||||
Log.d(Constants.TAG, "importKeys started");
|
||||
|
||||
public void exportKeys() {
|
||||
showDialog(Id.dialog.exporting);
|
||||
mTask = Id.task.export_keys;
|
||||
startThread();
|
||||
}
|
||||
// Send all information needed to service to import key in other thread
|
||||
Intent intent = new Intent(this, ApgService.class);
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String error = null;
|
||||
intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_IMPORT_KEY);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
Message msg = new Message();
|
||||
|
||||
try {
|
||||
InputStream importInputStream = null;
|
||||
OutputStream exportOutputStream = null;
|
||||
long size = 0;
|
||||
if (mTask == Id.task.import_keys) {
|
||||
if (mImportData != null) {
|
||||
byte[] bytes = mImportData.getBytes();
|
||||
size = bytes.length;
|
||||
importInputStream = new ByteArrayInputStream(bytes);
|
||||
} else {
|
||||
File file = new File(mImportFilename);
|
||||
size = file.length();
|
||||
importInputStream = new FileInputStream(file);
|
||||
}
|
||||
} else {
|
||||
exportOutputStream = new FileOutputStream(mExportFilename);
|
||||
}
|
||||
data.putInt(ApgService.IMPORT_KEY_TYPE, mKeyType);
|
||||
|
||||
if (mTask == Id.task.import_keys) {
|
||||
data = PGPMain.importKeyRings(this, mKeyType, new InputData(importInputStream,
|
||||
size), this);
|
||||
} else {
|
||||
Vector<Integer> keyRingIds = new Vector<Integer>();
|
||||
if (mSelectedItem == -1) {
|
||||
keyRingIds = PGPMain
|
||||
.getKeyRingIds(mKeyType == Id.type.public_key ? Id.database.type_public
|
||||
: Id.database.type_secret);
|
||||
} else {
|
||||
int keyRingId = mListAdapter.getKeyRingId(mSelectedItem);
|
||||
keyRingIds.add(keyRingId);
|
||||
mSelectedItem = -1;
|
||||
}
|
||||
data = PGPMain.exportKeyRings(this, keyRingIds, exportOutputStream, this);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
error = getString(R.string.error_fileNotFound);
|
||||
} catch (IOException e) {
|
||||
error = "" + e;
|
||||
} catch (PGPException e) {
|
||||
error = "" + e;
|
||||
} catch (PGPMain.GeneralException e) {
|
||||
error = "" + e;
|
||||
}
|
||||
|
||||
mImportData = null;
|
||||
|
||||
if (mTask == Id.task.import_keys) {
|
||||
data.putInt(Constants.extras.STATUS, Id.message.import_done);
|
||||
if (mImportData != null) {
|
||||
data.putInt(ApgService.TARGET, ApgService.TARGET_BYTES);
|
||||
data.putByteArray(ApgService.IMPORT_BYTES, mImportData.getBytes());
|
||||
} else {
|
||||
data.putInt(Constants.extras.STATUS, Id.message.export_done);
|
||||
data.putInt(ApgService.TARGET, ApgService.TARGET_FILE);
|
||||
data.putString(ApgService.IMPORT_FILENAME, mImportFilename);
|
||||
}
|
||||
|
||||
if (error != null) {
|
||||
data.putString(EXTRA_ERROR, error);
|
||||
}
|
||||
intent.putExtra(ApgService.EXTRA_DATA, data);
|
||||
|
||||
msg.setData(data);
|
||||
sendMessage(msg);
|
||||
}
|
||||
// create progress dialog
|
||||
ProgressDialogFragment importingDialog = ProgressDialogFragment.newInstance(
|
||||
R.string.progress_importing, ProgressDialog.STYLE_HORIZONTAL);
|
||||
|
||||
protected void deleteKey(int keyRingId) {
|
||||
PGPMain.deleteKey(keyRingId);
|
||||
refreshList();
|
||||
}
|
||||
// Message is received after importing is done in ApgService
|
||||
ApgHandler saveHandler = new ApgHandler(this, importingDialog) {
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard ApgHandler first
|
||||
super.handleMessage(message);
|
||||
|
||||
protected void refreshList() {
|
||||
mListAdapter.rebuild(true);
|
||||
mListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
if (message.arg1 == ApgHandler.MESSAGE_OKAY) {
|
||||
// get returned data bundle
|
||||
Bundle returnData = message.getData();
|
||||
|
||||
@Override
|
||||
public void doneCallback(Message msg) {
|
||||
super.doneCallback(msg);
|
||||
|
||||
Bundle data = msg.getData();
|
||||
if (data != null) {
|
||||
int type = data.getInt(Constants.extras.STATUS);
|
||||
switch (type) {
|
||||
case Id.message.import_done: {
|
||||
removeDialog(Id.dialog.importing);
|
||||
|
||||
String error = data.getString(EXTRA_ERROR);
|
||||
if (error != null) {
|
||||
Toast.makeText(KeyListActivity.this, getString(R.string.errorMessage, error),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
int added = data.getInt("added");
|
||||
int updated = data.getInt("updated");
|
||||
int bad = data.getInt("bad");
|
||||
String message;
|
||||
int added = returnData.getInt("added");
|
||||
int updated = returnData.getInt("updated");
|
||||
int bad = returnData.getInt("bad");
|
||||
String toastMessage;
|
||||
if (added > 0 && updated > 0) {
|
||||
message = getString(R.string.keysAddedAndUpdated, added, updated);
|
||||
toastMessage = getString(R.string.keysAddedAndUpdated, added, updated);
|
||||
} else if (added > 0) {
|
||||
message = getString(R.string.keysAdded, added);
|
||||
toastMessage = getString(R.string.keysAdded, added);
|
||||
} else if (updated > 0) {
|
||||
message = getString(R.string.keysUpdated, updated);
|
||||
toastMessage = getString(R.string.keysUpdated, updated);
|
||||
} else {
|
||||
message = getString(R.string.noKeysAddedOrUpdated);
|
||||
toastMessage = getString(R.string.noKeysAddedOrUpdated);
|
||||
}
|
||||
Toast.makeText(KeyListActivity.this, message, Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(KeyListActivity.this, toastMessage, Toast.LENGTH_SHORT).show();
|
||||
if (bad > 0) {
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(KeyListActivity.this);
|
||||
|
||||
alert.setIcon(android.R.drawable.ic_dialog_alert);
|
||||
alert.setTitle(R.string.warning);
|
||||
alert.setMessage(this.getString(R.string.badKeysEncountered, bad));
|
||||
alert.setMessage(KeyListActivity.this.getString(
|
||||
R.string.badKeysEncountered, bad));
|
||||
|
||||
alert.setPositiveButton(android.R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@ -443,41 +344,94 @@ public class KeyListActivity extends BaseActivity {
|
||||
alert.create().show();
|
||||
} else if (mDeleteAfterImport) {
|
||||
// everything went well, so now delete, if that was turned on
|
||||
setDeleteFile(mImportFilename);
|
||||
showDialog(Id.dialog.delete_file);
|
||||
DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment
|
||||
.newInstance(mImportFilename);
|
||||
deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog");
|
||||
}
|
||||
refreshList();
|
||||
|
||||
}
|
||||
refreshList();
|
||||
break;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
case Id.message.export_done: {
|
||||
removeDialog(Id.dialog.exporting);
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(saveHandler);
|
||||
intent.putExtra(ApgService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
String error = data.getString(EXTRA_ERROR);
|
||||
if (error != null) {
|
||||
Toast.makeText(KeyListActivity.this, getString(R.string.errorMessage, error),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
int exported = data.getInt("exported");
|
||||
String message;
|
||||
if (exported == 1) {
|
||||
message = getString(R.string.keyExported);
|
||||
} else if (exported > 0) {
|
||||
message = getString(R.string.keysExported, exported);
|
||||
} else {
|
||||
message = getString(R.string.noKeysExported);
|
||||
}
|
||||
Toast.makeText(KeyListActivity.this, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
break;
|
||||
}
|
||||
// show progress dialog
|
||||
importingDialog.show(getSupportFragmentManager(), "importingDialog");
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// start service with intent
|
||||
startService(intent);
|
||||
}
|
||||
|
||||
public void exportKeys() {
|
||||
Log.d(Constants.TAG, "exportKeys started");
|
||||
|
||||
// Send all information needed to service to export key in other thread
|
||||
Intent intent = new Intent(this, ApgService.class);
|
||||
|
||||
intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_EXPORT_KEY);
|
||||
|
||||
// fill values for this action
|
||||
Bundle data = new Bundle();
|
||||
|
||||
data.putString(ApgService.EXPORT_FILENAME, mExportFilename);
|
||||
data.putInt(ApgService.EXPORT_KEY_TYPE, mKeyType);
|
||||
|
||||
if (mSelectedItem == -1) {
|
||||
data.putBoolean(ApgService.EXPORT_ALL, true);
|
||||
} else {
|
||||
int keyRingId = mListAdapter.getKeyRingId(mSelectedItem);
|
||||
data.putInt(ApgService.EXPORT_KEY_RING_ID, keyRingId);
|
||||
mSelectedItem = -1;
|
||||
}
|
||||
|
||||
intent.putExtra(ApgService.EXTRA_DATA, data);
|
||||
|
||||
// create progress dialog
|
||||
ProgressDialogFragment exportingDialog = ProgressDialogFragment.newInstance(
|
||||
R.string.progress_exporting, ProgressDialog.STYLE_HORIZONTAL);
|
||||
|
||||
// Message is received after exporting is done in ApgService
|
||||
ApgHandler exportHandler = new ApgHandler(this, exportingDialog) {
|
||||
public void handleMessage(Message message) {
|
||||
// handle messages by standard ApgHandler first
|
||||
super.handleMessage(message);
|
||||
|
||||
if (message.arg1 == ApgHandler.MESSAGE_OKAY) {
|
||||
// get returned data bundle
|
||||
Bundle returnData = message.getData();
|
||||
|
||||
int exported = returnData.getInt("exported");
|
||||
String toastMessage;
|
||||
if (exported == 1) {
|
||||
toastMessage = getString(R.string.keyExported);
|
||||
} else if (exported > 0) {
|
||||
toastMessage = getString(R.string.keysExported, exported);
|
||||
} else {
|
||||
toastMessage = getString(R.string.noKeysExported);
|
||||
}
|
||||
Toast.makeText(KeyListActivity.this, toastMessage, Toast.LENGTH_SHORT).show();
|
||||
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(exportHandler);
|
||||
intent.putExtra(ApgService.EXTRA_MESSENGER, messenger);
|
||||
|
||||
// show progress dialog
|
||||
exportingDialog.show(getSupportFragmentManager(), "exportingDialog");
|
||||
|
||||
// start service with intent
|
||||
startService(intent);
|
||||
}
|
||||
|
||||
protected void refreshList() {
|
||||
mListAdapter.rebuild(true);
|
||||
mListAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
protected class KeyListAdapter extends BaseExpandableListAdapter {
|
||||
|
@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thialfihar.android.apg.ui;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import org.thialfihar.android.apg.R;
|
||||
import org.thialfihar.android.apg.helper.PGPMain;
|
||||
import org.thialfihar.android.apg.helper.Preferences;
|
||||
|
||||
import android.app.ListActivity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class MailListActivity extends ListActivity {
|
||||
LayoutInflater mInflater = null;
|
||||
|
||||
public static final String EXTRA_ACCOUNT = "account";
|
||||
|
||||
private static class Conversation {
|
||||
public long id;
|
||||
public String subject;
|
||||
public Vector<Message> messages;
|
||||
|
||||
public Conversation(long id, String subject) {
|
||||
this.id = id;
|
||||
this.subject = subject;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Message {
|
||||
public Conversation parent;
|
||||
public long id;
|
||||
public String subject;
|
||||
public String fromAddress;
|
||||
public String data;
|
||||
public String replyTo;
|
||||
public boolean signedOnly;
|
||||
|
||||
public Message(Conversation parent, long id, String subject, String fromAddress,
|
||||
String replyTo, String data, boolean signedOnly) {
|
||||
this.parent = parent;
|
||||
this.id = id;
|
||||
this.subject = subject;
|
||||
this.fromAddress = fromAddress;
|
||||
this.replyTo = replyTo;
|
||||
this.data = data;
|
||||
if (this.replyTo == null || this.replyTo.equals("")) {
|
||||
this.replyTo = this.fromAddress;
|
||||
}
|
||||
this.signedOnly = signedOnly;
|
||||
}
|
||||
}
|
||||
|
||||
private Vector<Conversation> mConversations;
|
||||
private Vector<Message> mMessages;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
Preferences prefs = Preferences.getPreferences(this);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
mConversations = new Vector<Conversation>();
|
||||
mMessages = new Vector<Message>();
|
||||
|
||||
String account = getIntent().getExtras().getString(EXTRA_ACCOUNT);
|
||||
// TODO: what if account is null?
|
||||
Uri uri = Uri.parse("content://gmail-ls/conversations/" + account);
|
||||
Cursor cursor = managedQuery(uri, new String[] { "conversation_id", "subject" }, null,
|
||||
null, null);
|
||||
for (int i = 0; i < cursor.getCount(); ++i) {
|
||||
cursor.moveToPosition(i);
|
||||
|
||||
int idIndex = cursor.getColumnIndex("conversation_id");
|
||||
int subjectIndex = cursor.getColumnIndex("subject");
|
||||
long conversationId = cursor.getLong(idIndex);
|
||||
Conversation conversation = new Conversation(conversationId,
|
||||
cursor.getString(subjectIndex));
|
||||
Uri messageUri = Uri.withAppendedPath(uri, "" + conversationId + "/messages");
|
||||
Cursor messageCursor = managedQuery(messageUri, new String[] { "messageId", "subject",
|
||||
"fromAddress", "replyToAddresses", "body" }, null, null, null);
|
||||
Vector<Message> messages = new Vector<Message>();
|
||||
for (int j = 0; j < messageCursor.getCount(); ++j) {
|
||||
messageCursor.moveToPosition(j);
|
||||
idIndex = messageCursor.getColumnIndex("messageId");
|
||||
subjectIndex = messageCursor.getColumnIndex("subject");
|
||||
int fromAddressIndex = messageCursor.getColumnIndex("fromAddress");
|
||||
int replyToIndex = messageCursor.getColumnIndex("replyToAddresses");
|
||||
int bodyIndex = messageCursor.getColumnIndex("body");
|
||||
String data = messageCursor.getString(bodyIndex);
|
||||
data = Html.fromHtml(data).toString();
|
||||
boolean signedOnly = false;
|
||||
Matcher matcher = PGPMain.PGP_MESSAGE.matcher(data);
|
||||
if (matcher.matches()) {
|
||||
data = matcher.group(1);
|
||||
} else {
|
||||
matcher = PGPMain.PGP_SIGNED_MESSAGE.matcher(data);
|
||||
if (matcher.matches()) {
|
||||
data = matcher.group(1);
|
||||
signedOnly = true;
|
||||
} else {
|
||||
data = null;
|
||||
}
|
||||
}
|
||||
Message message = new Message(conversation, messageCursor.getLong(idIndex),
|
||||
messageCursor.getString(subjectIndex),
|
||||
messageCursor.getString(fromAddressIndex),
|
||||
messageCursor.getString(replyToIndex), data, signedOnly);
|
||||
|
||||
messages.add(message);
|
||||
mMessages.add(message);
|
||||
}
|
||||
conversation.messages = messages;
|
||||
mConversations.add(conversation);
|
||||
}
|
||||
|
||||
setListAdapter(new MailboxAdapter());
|
||||
getListView().setOnItemClickListener(new OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
|
||||
Intent intent = new Intent(MailListActivity.this, DecryptActivity.class);
|
||||
intent.setAction(DecryptActivity.ACTION_DECRYPT);
|
||||
Message message = (Message) ((MailboxAdapter) getListAdapter()).getItem(position);
|
||||
intent.putExtra(DecryptActivity.EXTRA_TEXT, message.data);
|
||||
intent.putExtra(DecryptActivity.EXTRA_SUBJECT, message.subject);
|
||||
intent.putExtra(DecryptActivity.EXTRA_REPLY_TO, message.replyTo);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class MailboxAdapter extends BaseAdapter implements ListAdapter {
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int position) {
|
||||
Message message = (Message) getItem(position);
|
||||
return message.data != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mMessages.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
return mMessages.get(position);
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return mMessages.get(position).id;
|
||||
}
|
||||
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View view = mInflater.inflate(R.layout.mailbox_message_item, null);
|
||||
|
||||
Message message = (Message) getItem(position);
|
||||
|
||||
TextView subject = (TextView) view.findViewById(R.id.subject);
|
||||
TextView email = (TextView) view.findViewById(R.id.emailAddress);
|
||||
ImageView status = (ImageView) view.findViewById(R.id.ic_status);
|
||||
|
||||
subject.setText(message.subject);
|
||||
email.setText(message.fromAddress);
|
||||
if (message.data != null) {
|
||||
if (message.signedOnly) {
|
||||
status.setImageResource(R.drawable.signed);
|
||||
} else {
|
||||
status.setImageResource(R.drawable.encrypted);
|
||||
}
|
||||
status.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
status.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
}
|
||||
}
|
@ -17,9 +17,6 @@
|
||||
|
||||
package org.thialfihar.android.apg.ui;
|
||||
|
||||
import java.security.Security;
|
||||
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.thialfihar.android.apg.Id;
|
||||
import org.thialfihar.android.apg.R;
|
||||
|
||||
@ -33,9 +30,6 @@ import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
public class MainActivity extends SherlockActivity {
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
public void manageKeysOnClick(View view) {
|
||||
startActivity(new Intent(this, PublicKeyListActivity.class));
|
||||
|
@ -19,16 +19,19 @@ package org.thialfihar.android.apg.ui;
|
||||
import org.thialfihar.android.apg.R;
|
||||
import org.thialfihar.android.apg.Constants;
|
||||
import org.thialfihar.android.apg.Id;
|
||||
import org.thialfihar.android.apg.deprecated.AskForPassphrase;
|
||||
import org.thialfihar.android.apg.helper.PGPHelper;
|
||||
import org.thialfihar.android.apg.helper.PGPMain;
|
||||
import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment;
|
||||
import org.thialfihar.android.apg.util.Log;
|
||||
|
||||
import com.actionbarsherlock.view.Menu;
|
||||
import com.actionbarsherlock.view.MenuItem;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.View;
|
||||
@ -39,6 +42,7 @@ import android.widget.ExpandableListView.OnChildClickListener;
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
|
||||
public class SecretKeyListActivity extends KeyListActivity implements OnChildClickListener {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
mExportFilename = Constants.path.APP_DIR + "/secexport.asc";
|
||||
@ -86,7 +90,7 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
|
||||
menu.add(0, Id.menu.edit, 0, R.string.menu_editKey);
|
||||
menu.add(0, Id.menu.export, 1, R.string.menu_exportKey);
|
||||
menu.add(0, Id.menu.delete, 2, R.string.menu_deleteKey);
|
||||
menu.add(0, Id.menu.share, 2, R.string.menu_share);
|
||||
menu.add(0, Id.menu.share_qr_code, 2, R.string.menu_share);
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,12 +111,13 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
|
||||
return true;
|
||||
}
|
||||
|
||||
case Id.menu.share: {
|
||||
case Id.menu.share_qr_code: {
|
||||
mSelectedItem = groupPosition;
|
||||
|
||||
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter())
|
||||
.getGroupId(mSelectedItem);
|
||||
String msg = keyId + "," + PGPHelper.getFingerPrint(keyId);
|
||||
// String msg = keyId + "," + PGPHelper.getFingerPrint(keyId);
|
||||
String msg = PGPHelper.getPubkeyAsArmoredString(keyId);
|
||||
|
||||
new IntentIntegrator(this).shareText(msg);
|
||||
}
|
||||
@ -130,37 +135,43 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
case Id.dialog.pass_phrase: {
|
||||
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter())
|
||||
.getGroupId(mSelectedItem);
|
||||
return AskForPassphrase.createDialog(this, keyId, this);
|
||||
}
|
||||
|
||||
default: {
|
||||
return super.onCreateDialog(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkPassPhraseAndEdit() {
|
||||
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()).getGroupId(mSelectedItem);
|
||||
String passPhrase = PGPMain.getCachedPassPhrase(keyId);
|
||||
if (passPhrase == null) {
|
||||
showDialog(Id.dialog.pass_phrase);
|
||||
showPassphraseDialog(keyId);
|
||||
} else {
|
||||
PGPMain.setEditPassPhrase(passPhrase);
|
||||
editKey();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passPhraseCallback(long keyId, String passPhrase) {
|
||||
super.passPhraseCallback(keyId, passPhrase);
|
||||
PGPMain.setEditPassPhrase(passPhrase);
|
||||
editKey();
|
||||
private void showPassphraseDialog(final long secretKeyId) {
|
||||
// Message is received after passphrase is cached
|
||||
Handler returnHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
|
||||
String passPhrase = PGPMain.getCachedPassPhrase(secretKeyId);
|
||||
PGPMain.setEditPassPhrase(passPhrase);
|
||||
editKey();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Create a new Messenger for the communication back
|
||||
Messenger messenger = new Messenger(returnHandler);
|
||||
|
||||
try {
|
||||
PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(
|
||||
messenger, secretKeyId);
|
||||
|
||||
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
||||
} catch (PGPMain.GeneralException e) {
|
||||
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
||||
// send message to handler to start encryption directly
|
||||
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
||||
}
|
||||
}
|
||||
|
||||
private void createKey() {
|
||||
|
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thialfihar.android.apg.ui.dialog;
|
||||
|
||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.thialfihar.android.apg.Constants;
|
||||
import org.thialfihar.android.apg.Id;
|
||||
import org.thialfihar.android.apg.R;
|
||||
import org.thialfihar.android.apg.helper.PGPHelper;
|
||||
import org.thialfihar.android.apg.helper.PGPMain;
|
||||
import org.thialfihar.android.apg.util.Log;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
|
||||
public class DeleteKeyDialogFragment extends DialogFragment {
|
||||
|
||||
private Messenger mMessenger;
|
||||
|
||||
private static final String ARG_MESSENGER = "messenger";
|
||||
private static final String ARG_DELETE_KEY_RING_ID = "delete_file";
|
||||
private static final String ARG_KEY_TYPE = "key_type";
|
||||
|
||||
public static final int MESSAGE_OKAY = 1;
|
||||
|
||||
/**
|
||||
* Creates new instance of this delete file dialog fragment
|
||||
*/
|
||||
public static DeleteKeyDialogFragment newInstance(Messenger messenger, int deleteKeyRingId,
|
||||
int keyType) {
|
||||
DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment();
|
||||
Bundle args = new Bundle();
|
||||
|
||||
args.putParcelable(ARG_MESSENGER, messenger);
|
||||
args.putInt(ARG_DELETE_KEY_RING_ID, deleteKeyRingId);
|
||||
args.putInt(ARG_KEY_TYPE, keyType);
|
||||
|
||||
frag.setArguments(args);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates dialog
|
||||
*/
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final FragmentActivity activity = getActivity();
|
||||
|
||||
final int deleteKeyRingId = getArguments().getInt(ARG_DELETE_KEY_RING_ID);
|
||||
final int keyType = getArguments().getInt(ARG_KEY_TYPE);
|
||||
|
||||
// TODO: better way to do this?
|
||||
String userId = "<unknown>";
|
||||
Object keyRing = PGPMain.getKeyRing(deleteKeyRingId);
|
||||
if (keyRing != null) {
|
||||
if (keyRing instanceof PGPPublicKeyRing) {
|
||||
userId = PGPHelper.getMainUserIdSafe(activity,
|
||||
PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing));
|
||||
} else {
|
||||
userId = PGPHelper.getMainUserIdSafe(activity,
|
||||
PGPHelper.getMasterKey((PGPSecretKeyRing) keyRing));
|
||||
}
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.setTitle(R.string.warning);
|
||||
builder.setMessage(getString(
|
||||
keyType == Id.type.public_key ? R.string.keyDeletionConfirmation
|
||||
: R.string.secretKeyDeletionConfirmation, userId));
|
||||
builder.setIcon(android.R.drawable.ic_dialog_alert);
|
||||
builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
// deleteKey(deleteKeyRingId);
|
||||
PGPMain.deleteKey(deleteKeyRingId);
|
||||
|
||||
dismiss();
|
||||
|
||||
sendMessageToHandler(MESSAGE_OKAY);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send message back to handler which is initialized in a activity
|
||||
*
|
||||
* @param what
|
||||
* Message integer you want to send
|
||||
*/
|
||||
private void sendMessageToHandler(Integer what) {
|
||||
Message msg = Message.obtain();
|
||||
msg.what = what;
|
||||
|
||||
try {
|
||||
mMessenger.send(msg);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
|
||||
} catch (NullPointerException e) {
|
||||
Log.w(Constants.TAG, "Messenger is null!", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.thialfihar.android.apg.ui.dialog;
|
||||
|
||||
import org.thialfihar.android.apg.helper.PGPHelper;
|
||||
import org.thialfihar.android.apg.Constants;
|
||||
import org.thialfihar.android.apg.Id;
|
||||
import org.thialfihar.android.apg.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnCancelListener;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
|
||||
import org.thialfihar.android.apg.ui.KeyServerQueryActivity;
|
||||
import org.thialfihar.android.apg.util.Log;
|
||||
|
||||
public class LookupUnknownKeyDialogFragment extends DialogFragment {
|
||||
|
||||
private Messenger mMessenger;
|
||||
|
||||
private static final String ARG_MESSENGER = "messenger";
|
||||
private static final String ARG_UNKNOWN_KEY_ID = "unknown_key_id";
|
||||
|
||||
public static final int MESSAGE_OKAY = 1;
|
||||
public static final int MESSAGE_CANCEL = 2;
|
||||
|
||||
/**
|
||||
* Creates new instance of this dialog fragment
|
||||
*
|
||||
* @param messenger
|
||||
* @param unknownKeyId
|
||||
* @return
|
||||
*/
|
||||
public static LookupUnknownKeyDialogFragment newInstance(Messenger messenger, long unknownKeyId) {
|
||||
LookupUnknownKeyDialogFragment frag = new LookupUnknownKeyDialogFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putLong(ARG_UNKNOWN_KEY_ID, unknownKeyId);
|
||||
args.putParcelable(ARG_MESSENGER, messenger);
|
||||
|
||||
frag.setArguments(args);
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates dialog
|
||||
*/
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Activity activity = getActivity();
|
||||
|
||||
final long unknownKeyId = getArguments().getLong(ARG_UNKNOWN_KEY_ID);
|
||||
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
|
||||
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
|
||||
|
||||
alert.setIcon(android.R.drawable.ic_dialog_alert);
|
||||
alert.setTitle(R.string.title_unknownSignatureKey);
|
||||
alert.setMessage(getString(R.string.lookupUnknownKey,
|
||||
PGPHelper.getSmallFingerPrint(unknownKeyId)));
|
||||
|
||||
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dismiss();
|
||||
|
||||
sendMessageToHandler(MESSAGE_OKAY);
|
||||
|
||||
Intent intent = new Intent(activity, KeyServerQueryActivity.class);
|
||||
intent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID);
|
||||
intent.putExtra(KeyServerQueryActivity.EXTRA_KEY_ID, unknownKeyId);
|
||||
startActivityForResult(intent, Id.request.look_up_key_id);
|
||||
}
|
||||
});
|
||||
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dismiss();
|
||||
|
||||
sendMessageToHandler(MESSAGE_CANCEL);
|
||||
}
|
||||
});
|
||||
alert.setCancelable(true);
|
||||
alert.setOnCancelListener(new OnCancelListener() {
|
||||
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
sendMessageToHandler(MESSAGE_CANCEL);
|
||||
}
|
||||
});
|
||||
|
||||
return alert.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send message back to handler which is initialized in a activity
|
||||
*
|
||||
* @param what
|
||||
* Message integer you want to send
|
||||
*/
|
||||
private void sendMessageToHandler(Integer what) {
|
||||
Message msg = Message.obtain();
|
||||
msg.what = what;
|
||||
|
||||
try {
|
||||
mMessenger.send(msg);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
|
||||
} catch (NullPointerException e) {
|
||||
Log.w(Constants.TAG, "Messenger is null!", e);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user