mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-14 04:45:04 -05:00
Merge branch 'master' of github.com:open-keychain/open-keychain
This commit is contained in:
commit
bdf0436c94
@ -121,14 +121,7 @@ public class ExportHelper {
|
|||||||
// Message is received after exporting is done in KeychainIntentService
|
// Message is received after exporting is done in KeychainIntentService
|
||||||
KeychainIntentServiceHandler exportHandler = new KeychainIntentServiceHandler(mActivity,
|
KeychainIntentServiceHandler exportHandler = new KeychainIntentServiceHandler(mActivity,
|
||||||
mActivity.getString(R.string.progress_exporting),
|
mActivity.getString(R.string.progress_exporting),
|
||||||
ProgressDialog.STYLE_HORIZONTAL,
|
ProgressDialog.STYLE_HORIZONTAL) {
|
||||||
true,
|
|
||||||
new DialogInterface.OnCancelListener() {
|
|
||||||
@Override
|
|
||||||
public void onCancel(DialogInterface dialogInterface) {
|
|
||||||
mActivity.stopService(intent);
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
public void handleMessage(Message message) {
|
public void handleMessage(Message message) {
|
||||||
// handle messages by standard KeychainIntentServiceHandler first
|
// handle messages by standard KeychainIntentServiceHandler first
|
||||||
super.handleMessage(message);
|
super.handleMessage(message);
|
||||||
|
@ -33,6 +33,8 @@ import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
|||||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
|
import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel;
|
||||||
|
import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType;
|
||||||
import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog;
|
import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog;
|
||||||
import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult;
|
import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult;
|
||||||
import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult;
|
import org.sufficientlysecure.keychain.service.OperationResults.SaveKeyringResult;
|
||||||
@ -46,6 +48,7 @@ import java.io.OutputStream;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class PgpImportExport {
|
public class PgpImportExport {
|
||||||
|
|
||||||
@ -56,6 +59,7 @@ public class PgpImportExport {
|
|||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private Progressable mProgressable;
|
private Progressable mProgressable;
|
||||||
|
private AtomicBoolean mCancelled;
|
||||||
|
|
||||||
private KeychainServiceListener mKeychainServiceListener;
|
private KeychainServiceListener mKeychainServiceListener;
|
||||||
|
|
||||||
@ -72,6 +76,14 @@ public class PgpImportExport {
|
|||||||
this.mProviderHelper = providerHelper;
|
this.mProviderHelper = providerHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PgpImportExport(Context context, ProviderHelper providerHelper, Progressable progressable, AtomicBoolean cancelled) {
|
||||||
|
super();
|
||||||
|
mContext = context;
|
||||||
|
mProgressable = progressable;
|
||||||
|
mProviderHelper = providerHelper;
|
||||||
|
mCancelled = cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
public PgpImportExport(Context context,
|
public PgpImportExport(Context context,
|
||||||
Progressable progressable, KeychainServiceListener keychainListener) {
|
Progressable progressable, KeychainServiceListener keychainListener) {
|
||||||
super();
|
super();
|
||||||
@ -143,6 +155,11 @@ public class PgpImportExport {
|
|||||||
int position = 0;
|
int position = 0;
|
||||||
double progSteps = 100.0 / num;
|
double progSteps = 100.0 / num;
|
||||||
for (ParcelableKeyRing entry : new IterableIterator<ParcelableKeyRing>(entries)) {
|
for (ParcelableKeyRing entry : new IterableIterator<ParcelableKeyRing>(entries)) {
|
||||||
|
// Has this action been cancelled? If so, don't proceed any further
|
||||||
|
if (mCancelled != null && mCancelled.get()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
UncachedKeyRing key = UncachedKeyRing.decodeFromData(entry.getBytes());
|
UncachedKeyRing key = UncachedKeyRing.decodeFromData(entry.getBytes());
|
||||||
|
|
||||||
@ -208,9 +225,13 @@ public class PgpImportExport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (log.containsWarnings()) {
|
if (log.containsWarnings()) {
|
||||||
resultType |= ImportKeyResult.RESULT_WITH_WARNINGS;
|
resultType |= ImportKeyResult.RESULT_WARNINGS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (mCancelled != null && mCancelled.get()) {
|
||||||
|
log.add(LogLevel.CANCELLED, LogType.MSG_OPERATION_CANCELLED, 0);
|
||||||
|
resultType |= ImportKeyResult.RESULT_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
return new ImportKeyResult(resultType, log, newKeys, oldKeys, badKeys, secret);
|
return new ImportKeyResult(resultType, log, newKeys, oldKeys, badKeys, secret);
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ import java.util.Arrays;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the single place where ALL operations that actually modify a PGP public or secret
|
* This class is the single place where ALL operations that actually modify a PGP public or secret
|
||||||
@ -85,6 +86,7 @@ import java.util.Stack;
|
|||||||
*/
|
*/
|
||||||
public class PgpKeyOperation {
|
public class PgpKeyOperation {
|
||||||
private Stack<Progressable> mProgress;
|
private Stack<Progressable> mProgress;
|
||||||
|
private AtomicBoolean mCancelled;
|
||||||
|
|
||||||
// most preferred is first
|
// most preferred is first
|
||||||
private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{
|
private static final int[] PREFERRED_SYMMETRIC_ALGORITHMS = new int[]{
|
||||||
@ -134,6 +136,15 @@ public class PgpKeyOperation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PgpKeyOperation(Progressable progress, AtomicBoolean cancelled) {
|
||||||
|
this(progress);
|
||||||
|
mCancelled = cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkCancelled() {
|
||||||
|
return mCancelled != null && mCancelled.get();
|
||||||
|
}
|
||||||
|
|
||||||
private void subProgressPush(int from, int to) {
|
private void subProgressPush(int from, int to) {
|
||||||
if (mProgress == null) {
|
if (mProgress == null) {
|
||||||
return;
|
return;
|
||||||
@ -450,6 +461,12 @@ public class PgpKeyOperation {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
// Check if we were cancelled
|
||||||
|
if (checkCancelled()) {
|
||||||
|
log.add(LogLevel.CANCELLED, LogType.MSG_OPERATION_CANCELLED, indent);
|
||||||
|
return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
|
||||||
|
}
|
||||||
|
|
||||||
{ // work on master secret key
|
{ // work on master secret key
|
||||||
|
|
||||||
PGPPublicKey modifiedPublicKey = masterPublicKey;
|
PGPPublicKey modifiedPublicKey = masterPublicKey;
|
||||||
@ -640,6 +657,12 @@ public class PgpKeyOperation {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if we were cancelled - again
|
||||||
|
if (checkCancelled()) {
|
||||||
|
log.add(LogLevel.CANCELLED, LogType.MSG_OPERATION_CANCELLED, indent);
|
||||||
|
return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
|
||||||
|
}
|
||||||
|
|
||||||
// 4a. For each subkey change, generate new subkey binding certificate
|
// 4a. For each subkey change, generate new subkey binding certificate
|
||||||
subProgressPush(50, 60);
|
subProgressPush(50, 60);
|
||||||
for (int i = 0; i < saveParcel.mChangeSubKeys.size(); i++) {
|
for (int i = 0; i < saveParcel.mChangeSubKeys.size(); i++) {
|
||||||
@ -750,6 +773,12 @@ public class PgpKeyOperation {
|
|||||||
subProgressPush(70, 90);
|
subProgressPush(70, 90);
|
||||||
for (int i = 0; i < saveParcel.mAddSubKeys.size(); i++) {
|
for (int i = 0; i < saveParcel.mAddSubKeys.size(); i++) {
|
||||||
|
|
||||||
|
// Check if we were cancelled - again. This operation is expensive so we do it each loop.
|
||||||
|
if (checkCancelled()) {
|
||||||
|
log.add(LogLevel.CANCELLED, LogType.MSG_OPERATION_CANCELLED, indent);
|
||||||
|
return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
|
||||||
|
}
|
||||||
|
|
||||||
progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / saveParcel.mAddSubKeys.size()));
|
progress(R.string.progress_modify_subkeyadd, (i-1) * (100 / saveParcel.mAddSubKeys.size()));
|
||||||
SaveKeyringParcel.SubkeyAdd add = saveParcel.mAddSubKeys.get(i);
|
SaveKeyringParcel.SubkeyAdd add = saveParcel.mAddSubKeys.get(i);
|
||||||
log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_NEW, indent,
|
log.add(LogLevel.INFO, LogType.MSG_MF_SUBKEY_NEW, indent,
|
||||||
@ -806,6 +835,12 @@ public class PgpKeyOperation {
|
|||||||
}
|
}
|
||||||
subProgressPop();
|
subProgressPop();
|
||||||
|
|
||||||
|
// Check if we were cancelled - again. This operation is expensive so we do it each loop.
|
||||||
|
if (checkCancelled()) {
|
||||||
|
log.add(LogLevel.CANCELLED, LogType.MSG_OPERATION_CANCELLED, indent);
|
||||||
|
return new EditKeyResult(EditKeyResult.RESULT_CANCELLED, log, null);
|
||||||
|
}
|
||||||
|
|
||||||
// 6. If requested, change passphrase
|
// 6. If requested, change passphrase
|
||||||
if (saveParcel.mNewPassphrase != null) {
|
if (saveParcel.mNewPassphrase != null) {
|
||||||
progress(R.string.progress_modify_passphrase, 90);
|
progress(R.string.progress_modify_passphrase, 90);
|
||||||
|
@ -54,6 +54,9 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData;
|
|||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
|
import org.sufficientlysecure.keychain.provider.KeychainDatabase;
|
||||||
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
import org.sufficientlysecure.keychain.provider.ProviderHelper;
|
||||||
|
import org.sufficientlysecure.keychain.service.OperationResultParcel.LogLevel;
|
||||||
|
import org.sufficientlysecure.keychain.service.OperationResultParcel.LogType;
|
||||||
|
import org.sufficientlysecure.keychain.service.OperationResultParcel.OperationLog;
|
||||||
import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult;
|
import org.sufficientlysecure.keychain.service.OperationResults.ConsolidateResult;
|
||||||
import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult;
|
import org.sufficientlysecure.keychain.service.OperationResults.EditKeyResult;
|
||||||
import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult;
|
import org.sufficientlysecure.keychain.service.OperationResults.ImportKeyResult;
|
||||||
@ -72,6 +75,7 @@ import java.io.IOException;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Service contains all important long lasting operations for APG. It receives Intents with
|
* This Service contains all important long lasting operations for APG. It receives Intents with
|
||||||
@ -92,7 +96,7 @@ public class KeychainIntentService extends IntentService
|
|||||||
|
|
||||||
public static final String ACTION_DECRYPT_METADATA = Constants.INTENT_PREFIX + "DECRYPT_METADATA";
|
public static final String ACTION_DECRYPT_METADATA = Constants.INTENT_PREFIX + "DECRYPT_METADATA";
|
||||||
|
|
||||||
public static final String ACTION_SAVE_KEYRING = Constants.INTENT_PREFIX + "SAVE_KEYRING";
|
public static final String ACTION_EDIT_KEYRING = Constants.INTENT_PREFIX + "EDIT_KEYRING";
|
||||||
|
|
||||||
public static final String ACTION_DELETE_FILE_SECURELY = Constants.INTENT_PREFIX
|
public static final String ACTION_DELETE_FILE_SECURELY = Constants.INTENT_PREFIX
|
||||||
+ "DELETE_FILE_SECURELY";
|
+ "DELETE_FILE_SECURELY";
|
||||||
@ -110,6 +114,8 @@ public class KeychainIntentService extends IntentService
|
|||||||
|
|
||||||
public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE";
|
public static final String ACTION_CONSOLIDATE = Constants.INTENT_PREFIX + "CONSOLIDATE";
|
||||||
|
|
||||||
|
public static final String ACTION_CANCEL = Constants.INTENT_PREFIX + "CANCEL";
|
||||||
|
|
||||||
/* keys for data bundle */
|
/* keys for data bundle */
|
||||||
|
|
||||||
// encrypt, decrypt, import export
|
// encrypt, decrypt, import export
|
||||||
@ -141,8 +147,8 @@ public class KeychainIntentService extends IntentService
|
|||||||
public static final String DECRYPT_PASSPHRASE = "passphrase";
|
public static final String DECRYPT_PASSPHRASE = "passphrase";
|
||||||
|
|
||||||
// save keyring
|
// save keyring
|
||||||
public static final String SAVE_KEYRING_PARCEL = "save_parcel";
|
public static final String EDIT_KEYRING_PARCEL = "save_parcel";
|
||||||
public static final String SAVE_KEYRING_PASSPHRASE = "passphrase";
|
public static final String EDIT_KEYRING_PASSPHRASE = "passphrase";
|
||||||
|
|
||||||
// delete file securely
|
// delete file securely
|
||||||
public static final String DELETE_FILE = "deleteFile";
|
public static final String DELETE_FILE = "deleteFile";
|
||||||
@ -196,6 +202,8 @@ public class KeychainIntentService extends IntentService
|
|||||||
Messenger mMessenger;
|
Messenger mMessenger;
|
||||||
|
|
||||||
private boolean mIsCanceled;
|
private boolean mIsCanceled;
|
||||||
|
// this attribute can possibly merged with the one above? not sure...
|
||||||
|
private AtomicBoolean mActionCanceled = new AtomicBoolean(false);
|
||||||
|
|
||||||
public KeychainIntentService() {
|
public KeychainIntentService() {
|
||||||
super("KeychainIntentService");
|
super("KeychainIntentService");
|
||||||
@ -214,6 +222,10 @@ public class KeychainIntentService extends IntentService
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void onHandleIntent(Intent intent) {
|
protected void onHandleIntent(Intent intent) {
|
||||||
|
|
||||||
|
// We have not been cancelled! (yet)
|
||||||
|
mActionCanceled.set(false);
|
||||||
|
|
||||||
Bundle extras = intent.getExtras();
|
Bundle extras = intent.getExtras();
|
||||||
if (extras == null) {
|
if (extras == null) {
|
||||||
Log.e(Constants.TAG, "Extras bundle is null!");
|
Log.e(Constants.TAG, "Extras bundle is null!");
|
||||||
@ -400,21 +412,22 @@ public class KeychainIntentService extends IntentService
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
sendErrorToHandler(e);
|
sendErrorToHandler(e);
|
||||||
}
|
}
|
||||||
} else if (ACTION_SAVE_KEYRING.equals(action)) {
|
} else if (ACTION_EDIT_KEYRING.equals(action)) {
|
||||||
try {
|
try {
|
||||||
/* Input */
|
/* Input */
|
||||||
SaveKeyringParcel saveParcel = data.getParcelable(SAVE_KEYRING_PARCEL);
|
SaveKeyringParcel saveParcel = data.getParcelable(EDIT_KEYRING_PARCEL);
|
||||||
if (saveParcel == null) {
|
if (saveParcel == null) {
|
||||||
Log.e(Constants.TAG, "bug: missing save_keyring_parcel in data!");
|
Log.e(Constants.TAG, "bug: missing save_keyring_parcel in data!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Operation */
|
/* Operation */
|
||||||
PgpKeyOperation keyOperations = new PgpKeyOperation(new ProgressScaler(this, 10, 60, 100));
|
PgpKeyOperation keyOperations =
|
||||||
|
new PgpKeyOperation(new ProgressScaler(this, 10, 60, 100), mActionCanceled);
|
||||||
EditKeyResult modifyResult;
|
EditKeyResult modifyResult;
|
||||||
|
|
||||||
if (saveParcel.mMasterKeyId != null) {
|
if (saveParcel.mMasterKeyId != null) {
|
||||||
String passphrase = data.getString(SAVE_KEYRING_PASSPHRASE);
|
String passphrase = data.getString(EDIT_KEYRING_PASSPHRASE);
|
||||||
CanonicalizedSecretKeyRing secRing =
|
CanonicalizedSecretKeyRing secRing =
|
||||||
new ProviderHelper(this).getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId);
|
new ProviderHelper(this).getCanonicalizedSecretKeyRing(saveParcel.mMasterKeyId);
|
||||||
|
|
||||||
@ -436,6 +449,20 @@ public class KeychainIntentService extends IntentService
|
|||||||
|
|
||||||
UncachedKeyRing ring = modifyResult.getRing();
|
UncachedKeyRing ring = modifyResult.getRing();
|
||||||
|
|
||||||
|
// Check if the action was cancelled
|
||||||
|
if (mActionCanceled.get()) {
|
||||||
|
OperationLog log = modifyResult.getLog();
|
||||||
|
// If it wasn't added before, add log entry
|
||||||
|
if (!modifyResult.cancelled()) {
|
||||||
|
log.add(LogLevel.CANCELLED, LogType.MSG_OPERATION_CANCELLED, 0);
|
||||||
|
}
|
||||||
|
// If so, just stop without saving
|
||||||
|
SaveKeyringResult saveResult = new SaveKeyringResult(
|
||||||
|
SaveKeyringResult.RESULT_CANCELLED, log, null);
|
||||||
|
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_OKAY, saveResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Save the keyring. The ProviderHelper is initialized with the previous log
|
// Save the keyring. The ProviderHelper is initialized with the previous log
|
||||||
SaveKeyringResult saveResult = new ProviderHelper(this, modifyResult.getLog())
|
SaveKeyringResult saveResult = new ProviderHelper(this, modifyResult.getLog())
|
||||||
.saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100));
|
.saveSecretKeyRing(ring, new ProgressScaler(this, 60, 95, 100));
|
||||||
@ -499,12 +526,17 @@ public class KeychainIntentService extends IntentService
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProviderHelper providerHelper = new ProviderHelper(this);
|
ProviderHelper providerHelper = new ProviderHelper(this);
|
||||||
PgpImportExport pgpImportExport = new PgpImportExport(this, providerHelper, this);
|
PgpImportExport pgpImportExport = new PgpImportExport(
|
||||||
|
this, providerHelper, this, mActionCanceled);
|
||||||
ImportKeyResult result = pgpImportExport.importKeyRings(entries);
|
ImportKeyResult result = pgpImportExport.importKeyRings(entries);
|
||||||
|
|
||||||
|
// we do this even on failure or cancellation!
|
||||||
if (result.mSecret > 0) {
|
if (result.mSecret > 0) {
|
||||||
|
// cannot cancel from here on out!
|
||||||
|
sendMessageToHandler(KeychainIntentServiceHandler.MESSAGE_PREVENT_CANCEL);
|
||||||
providerHelper.consolidateDatabaseStep1(this);
|
providerHelper.consolidateDatabaseStep1(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure new data is synced into contacts
|
// make sure new data is synced into contacts
|
||||||
ContactSyncAdapterService.requestSync();
|
ContactSyncAdapterService.requestSync();
|
||||||
|
|
||||||
@ -612,7 +644,6 @@ public class KeychainIntentService extends IntentService
|
|||||||
|
|
||||||
ArrayList<ParcelableKeyRing> keyRings = new ArrayList<ParcelableKeyRing>(entries.size());
|
ArrayList<ParcelableKeyRing> keyRings = new ArrayList<ParcelableKeyRing>(entries.size());
|
||||||
for (ImportKeysListEntry entry : entries) {
|
for (ImportKeysListEntry entry : entries) {
|
||||||
|
|
||||||
Keyserver server;
|
Keyserver server;
|
||||||
if (entry.getOrigin() == null) {
|
if (entry.getOrigin() == null) {
|
||||||
server = new HkpKeyserver(keyServer);
|
server = new HkpKeyserver(keyServer);
|
||||||
@ -874,6 +905,15 @@ public class KeychainIntentService extends IntentService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
if (ACTION_CANCEL.equals(intent.getAction())) {
|
||||||
|
mActionCanceled.set(true);
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
return super.onStartCommand(intent, flags, startId);
|
||||||
|
}
|
||||||
|
|
||||||
private String getOriginalFilename(Bundle data) throws PgpGeneralException, FileNotFoundException {
|
private String getOriginalFilename(Bundle data) throws PgpGeneralException, FileNotFoundException {
|
||||||
int target = data.getInt(TARGET);
|
int target = data.getInt(TARGET);
|
||||||
switch (target) {
|
switch (target) {
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
package org.sufficientlysecure.keychain.service;
|
package org.sufficientlysecure.keychain.service;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.DialogInterface.OnCancelListener;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
@ -37,6 +36,7 @@ public class KeychainIntentServiceHandler extends Handler {
|
|||||||
public static final int MESSAGE_OKAY = 1;
|
public static final int MESSAGE_OKAY = 1;
|
||||||
public static final int MESSAGE_EXCEPTION = 2;
|
public static final int MESSAGE_EXCEPTION = 2;
|
||||||
public static final int MESSAGE_UPDATE_PROGRESS = 3;
|
public static final int MESSAGE_UPDATE_PROGRESS = 3;
|
||||||
|
public static final int MESSAGE_PREVENT_CANCEL = 4;
|
||||||
|
|
||||||
// possible data keys for messages
|
// possible data keys for messages
|
||||||
public static final String DATA_ERROR = "error";
|
public static final String DATA_ERROR = "error";
|
||||||
@ -60,18 +60,16 @@ public class KeychainIntentServiceHandler extends Handler {
|
|||||||
|
|
||||||
public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
|
public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
|
||||||
int progressDialogStyle) {
|
int progressDialogStyle) {
|
||||||
this(activity, progressDialogMessage, progressDialogStyle, false, null);
|
this(activity, progressDialogMessage, progressDialogStyle, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
|
public KeychainIntentServiceHandler(Activity activity, String progressDialogMessage,
|
||||||
int progressDialogStyle, boolean cancelable,
|
int progressDialogStyle, boolean cancelable) {
|
||||||
OnCancelListener onCancelListener) {
|
|
||||||
this.mActivity = activity;
|
this.mActivity = activity;
|
||||||
this.mProgressDialogFragment = ProgressDialogFragment.newInstance(
|
this.mProgressDialogFragment = ProgressDialogFragment.newInstance(
|
||||||
progressDialogMessage,
|
progressDialogMessage,
|
||||||
progressDialogStyle,
|
progressDialogStyle,
|
||||||
cancelable,
|
cancelable);
|
||||||
onCancelListener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showProgressDialog(FragmentActivity activity) {
|
public void showProgressDialog(FragmentActivity activity) {
|
||||||
@ -126,6 +124,9 @@ public class KeychainIntentServiceHandler extends Handler {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MESSAGE_PREVENT_CANCEL:
|
||||||
|
mProgressDialogFragment.setPreventCancel(true);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log.e(Constants.TAG, "unknown handler message!");
|
Log.e(Constants.TAG, "unknown handler message!");
|
||||||
break;
|
break;
|
||||||
|
@ -55,13 +55,17 @@ public class OperationResultParcel implements Parcelable {
|
|||||||
|
|
||||||
public static final String EXTRA_RESULT = "operation_result";
|
public static final String EXTRA_RESULT = "operation_result";
|
||||||
|
|
||||||
/** Holds the overall result, the number specifying varying degrees of success. The first bit
|
/** Holds the overall result, the number specifying varying degrees of success:
|
||||||
* is 0 on overall success, 1 on overall failure. All other bits may be used for more specific
|
* - The first bit is 0 on overall success, 1 on overall failure
|
||||||
* conditions. */
|
* - The second bit indicates if the action was cancelled - may still be an error or success!
|
||||||
|
* - The third bit should be set if the operation succeeded with warnings
|
||||||
|
* All other bits may be used for more specific conditions. */
|
||||||
final int mResult;
|
final int mResult;
|
||||||
|
|
||||||
public static final int RESULT_OK = 0;
|
public static final int RESULT_OK = 0;
|
||||||
public static final int RESULT_ERROR = 1;
|
public static final int RESULT_ERROR = 1;
|
||||||
|
public static final int RESULT_CANCELLED = 2;
|
||||||
|
public static final int RESULT_WARNINGS = 4;
|
||||||
|
|
||||||
/// A list of log entries tied to the operation result.
|
/// A list of log entries tied to the operation result.
|
||||||
final OperationLog mLog;
|
final OperationLog mLog;
|
||||||
@ -82,7 +86,11 @@ public class OperationResultParcel implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean success() {
|
public boolean success() {
|
||||||
return (mResult & 1) == 0;
|
return (mResult & RESULT_ERROR) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean cancelled() {
|
||||||
|
return (mResult & RESULT_CANCELLED) == RESULT_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationLog getLog() {
|
public OperationLog getLog() {
|
||||||
@ -147,30 +155,25 @@ public class OperationResultParcel implements Parcelable {
|
|||||||
|
|
||||||
public SuperCardToast createNotify(final Activity activity) {
|
public SuperCardToast createNotify(final Activity activity) {
|
||||||
|
|
||||||
int resultType = getResult();
|
|
||||||
|
|
||||||
String str;
|
String str;
|
||||||
int duration, color;
|
int color;
|
||||||
|
|
||||||
// Not an overall failure
|
// Not an overall failure
|
||||||
if ((resultType & OperationResultParcel.RESULT_ERROR) == 0) {
|
if (cancelled()) {
|
||||||
|
color = Style.RED;
|
||||||
|
str = "operation cancelled!";
|
||||||
|
} else if (success()) {
|
||||||
if (getLog().containsWarnings()) {
|
if (getLog().containsWarnings()) {
|
||||||
color = Style.ORANGE;
|
color = Style.ORANGE;
|
||||||
} else {
|
} else {
|
||||||
color = Style.GREEN;
|
color = Style.GREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
str = "operation succeeded!";
|
str = "operation succeeded!";
|
||||||
// str = activity.getString(R.string.import_error);
|
// str = activity.getString(R.string.import_error);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
color = Style.RED;
|
color = Style.RED;
|
||||||
|
|
||||||
str = "operation failed";
|
str = "operation failed";
|
||||||
// str = activity.getString(R.string.import_error);
|
// str = activity.getString(R.string.import_error);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean button = getLog() != null && !getLog().isEmpty();
|
boolean button = getLog() != null && !getLog().isEmpty();
|
||||||
@ -223,7 +226,8 @@ public class OperationResultParcel implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public static enum LogType {
|
public static enum LogType {
|
||||||
|
|
||||||
INTERNAL_ERROR (R.string.internal_error),
|
MSG_INTERNAL_ERROR (R.string.msg_internal_error),
|
||||||
|
MSG_OPERATION_CANCELLED (R.string.msg_cancelled),
|
||||||
|
|
||||||
// import public
|
// import public
|
||||||
MSG_IP(R.string.msg_ip),
|
MSG_IP(R.string.msg_ip),
|
||||||
@ -440,6 +444,7 @@ public class OperationResultParcel implements Parcelable {
|
|||||||
ERROR, // should occur once at the end of a failed operation
|
ERROR, // should occur once at the end of a failed operation
|
||||||
START, // should occur once at the start of each independent operation
|
START, // should occur once at the start of each independent operation
|
||||||
OK, // should occur once at the end of a successful operation
|
OK, // should occur once at the end of a successful operation
|
||||||
|
CANCELLED, // should occur once at the end of a cancelled operation
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,6 +26,7 @@ import android.view.View;
|
|||||||
|
|
||||||
import com.github.johnpersano.supertoasts.SuperCardToast;
|
import com.github.johnpersano.supertoasts.SuperCardToast;
|
||||||
import com.github.johnpersano.supertoasts.SuperToast;
|
import com.github.johnpersano.supertoasts.SuperToast;
|
||||||
|
import com.github.johnpersano.supertoasts.SuperToast.Duration;
|
||||||
import com.github.johnpersano.supertoasts.util.OnClickWrapper;
|
import com.github.johnpersano.supertoasts.util.OnClickWrapper;
|
||||||
import com.github.johnpersano.supertoasts.util.Style;
|
import com.github.johnpersano.supertoasts.util.Style;
|
||||||
|
|
||||||
@ -44,16 +45,14 @@ public abstract class OperationResults {
|
|||||||
public final int mNewKeys, mUpdatedKeys, mBadKeys, mSecret;
|
public final int mNewKeys, mUpdatedKeys, mBadKeys, mSecret;
|
||||||
|
|
||||||
// At least one new key
|
// At least one new key
|
||||||
public static final int RESULT_OK_NEWKEYS = 2;
|
public static final int RESULT_OK_NEWKEYS = 8;
|
||||||
// At least one updated key
|
// At least one updated key
|
||||||
public static final int RESULT_OK_UPDATED = 4;
|
public static final int RESULT_OK_UPDATED = 16;
|
||||||
// At least one key failed (might still be an overall success)
|
// At least one key failed (might still be an overall success)
|
||||||
public static final int RESULT_WITH_ERRORS = 8;
|
public static final int RESULT_WITH_ERRORS = 32;
|
||||||
// There are warnings in the log
|
|
||||||
public static final int RESULT_WITH_WARNINGS = 16;
|
|
||||||
|
|
||||||
// No keys to import...
|
// No keys to import...
|
||||||
public static final int RESULT_FAIL_NOTHING = 32 + 1;
|
public static final int RESULT_FAIL_NOTHING = 64 + 1;
|
||||||
|
|
||||||
public boolean isOkBoth() {
|
public boolean isOkBoth() {
|
||||||
return (mResult & (RESULT_OK_NEWKEYS | RESULT_OK_UPDATED))
|
return (mResult & (RESULT_OK_NEWKEYS | RESULT_OK_UPDATED))
|
||||||
@ -119,15 +118,20 @@ public abstract class OperationResults {
|
|||||||
if ((resultType & OperationResultParcel.RESULT_ERROR) == 0) {
|
if ((resultType & OperationResultParcel.RESULT_ERROR) == 0) {
|
||||||
String withWarnings;
|
String withWarnings;
|
||||||
|
|
||||||
// Any warnings?
|
duration = Duration.EXTRA_LONG;
|
||||||
if ((resultType & ImportKeyResult.RESULT_WITH_WARNINGS) > 0) {
|
|
||||||
duration = 0;
|
|
||||||
color = Style.ORANGE;
|
|
||||||
withWarnings = activity.getResources().getString(R.string.import_with_warnings);
|
|
||||||
} else {
|
|
||||||
duration = SuperToast.Duration.LONG;
|
|
||||||
color = Style.GREEN;
|
color = Style.GREEN;
|
||||||
withWarnings = "";
|
withWarnings = "";
|
||||||
|
|
||||||
|
// Any warnings?
|
||||||
|
if ((resultType & ImportKeyResult.RESULT_WARNINGS) > 0) {
|
||||||
|
duration = 0;
|
||||||
|
color = Style.ORANGE;
|
||||||
|
withWarnings += activity.getString(R.string.import_with_warnings);
|
||||||
|
}
|
||||||
|
if ((resultType & ImportKeyResult.RESULT_CANCELLED) > 0) {
|
||||||
|
duration = 0;
|
||||||
|
color = Style.ORANGE;
|
||||||
|
withWarnings += activity.getString(R.string.import_with_cancelled);
|
||||||
}
|
}
|
||||||
|
|
||||||
// New and updated keys
|
// New and updated keys
|
||||||
@ -152,13 +156,14 @@ public abstract class OperationResults {
|
|||||||
duration = 0;
|
duration = 0;
|
||||||
color = Style.RED;
|
color = Style.RED;
|
||||||
if (isFailNothing()) {
|
if (isFailNothing()) {
|
||||||
str = activity.getString(R.string.import_error_nothing);
|
str = activity.getString((resultType & ImportKeyResult.RESULT_CANCELLED) > 0
|
||||||
|
? R.string.import_error_nothing_cancelled
|
||||||
|
: R.string.import_error_nothing);
|
||||||
} else {
|
} else {
|
||||||
str = activity.getString(R.string.import_error);
|
str = activity.getString(R.string.import_error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: externalize into Notify class?
|
|
||||||
boolean button = getLog() != null && !getLog().isEmpty();
|
boolean button = getLog() != null && !getLog().isEmpty();
|
||||||
SuperCardToast toast = new SuperCardToast(activity,
|
SuperCardToast toast = new SuperCardToast(activity,
|
||||||
button ? SuperToast.Type.BUTTON : SuperToast.Type.STANDARD,
|
button ? SuperToast.Type.BUTTON : SuperToast.Type.STANDARD,
|
||||||
@ -243,7 +248,7 @@ public abstract class OperationResults {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Some old key was updated
|
// Some old key was updated
|
||||||
public static final int UPDATED = 2;
|
public static final int UPDATED = 4;
|
||||||
|
|
||||||
// Public key was saved
|
// Public key was saved
|
||||||
public static final int SAVED_PUBLIC = 8;
|
public static final int SAVED_PUBLIC = 8;
|
||||||
|
@ -31,7 +31,6 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.spongycastle.bcpg.PublicKeyAlgorithmTags;
|
|
||||||
import org.spongycastle.bcpg.sig.KeyFlags;
|
import org.spongycastle.bcpg.sig.KeyFlags;
|
||||||
import org.sufficientlysecure.keychain.Constants;
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
@ -45,7 +44,6 @@ import org.sufficientlysecure.keychain.service.OperationResults;
|
|||||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
|
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.Algorithm;
|
||||||
import org.sufficientlysecure.keychain.util.Log;
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
import org.sufficientlysecure.keychain.util.Notify;
|
|
||||||
|
|
||||||
public class CreateKeyFinalFragment extends Fragment {
|
public class CreateKeyFinalFragment extends Fragment {
|
||||||
|
|
||||||
@ -126,7 +124,7 @@ public class CreateKeyFinalFragment extends Fragment {
|
|||||||
|
|
||||||
private void createKey() {
|
private void createKey() {
|
||||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||||
intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
|
intent.setAction(KeychainIntentService.ACTION_EDIT_KEYRING);
|
||||||
|
|
||||||
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
|
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
|
||||||
getActivity(),
|
getActivity(),
|
||||||
@ -178,7 +176,7 @@ public class CreateKeyFinalFragment extends Fragment {
|
|||||||
parcel.mNewPassphrase = mPassphrase;
|
parcel.mNewPassphrase = mPassphrase;
|
||||||
|
|
||||||
// get selected key entries
|
// get selected key entries
|
||||||
data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, parcel);
|
data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, parcel);
|
||||||
|
|
||||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||||
|
|
||||||
|
@ -507,7 +507,8 @@ public class EditKeyFragment extends LoaderFragment implements
|
|||||||
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
|
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
|
||||||
getActivity(),
|
getActivity(),
|
||||||
getString(R.string.progress_saving),
|
getString(R.string.progress_saving),
|
||||||
ProgressDialog.STYLE_HORIZONTAL) {
|
ProgressDialog.STYLE_HORIZONTAL,
|
||||||
|
true) {
|
||||||
public void handleMessage(Message message) {
|
public void handleMessage(Message message) {
|
||||||
// handle messages by standard KeychainIntentServiceHandler first
|
// handle messages by standard KeychainIntentServiceHandler first
|
||||||
super.handleMessage(message);
|
super.handleMessage(message);
|
||||||
@ -543,12 +544,12 @@ public class EditKeyFragment extends LoaderFragment implements
|
|||||||
|
|
||||||
// Send all information needed to service to import key in other thread
|
// Send all information needed to service to import key in other thread
|
||||||
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||||
intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING);
|
intent.setAction(KeychainIntentService.ACTION_EDIT_KEYRING);
|
||||||
|
|
||||||
// fill values for this action
|
// fill values for this action
|
||||||
Bundle data = new Bundle();
|
Bundle data = new Bundle();
|
||||||
data.putString(KeychainIntentService.SAVE_KEYRING_PASSPHRASE, passphrase);
|
data.putString(KeychainIntentService.EDIT_KEYRING_PASSPHRASE, passphrase);
|
||||||
data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, mSaveKeyringParcel);
|
data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, mSaveKeyringParcel);
|
||||||
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
|
||||||
|
|
||||||
// Create a new Messenger for the communication back
|
// Create a new Messenger for the communication back
|
||||||
@ -560,5 +561,6 @@ public class EditKeyFragment extends LoaderFragment implements
|
|||||||
|
|
||||||
// start service with intent
|
// start service with intent
|
||||||
getActivity().startService(intent);
|
getActivity().startService(intent);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ package org.sufficientlysecure.keychain.ui;
|
|||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.DialogInterface.OnCancelListener;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.nfc.NdefMessage;
|
import android.nfc.NdefMessage;
|
||||||
@ -447,7 +449,8 @@ public class ImportKeysActivity extends ActionBarActivity {
|
|||||||
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
|
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
|
||||||
this,
|
this,
|
||||||
getString(R.string.progress_importing),
|
getString(R.string.progress_importing),
|
||||||
ProgressDialog.STYLE_HORIZONTAL) {
|
ProgressDialog.STYLE_HORIZONTAL,
|
||||||
|
true) {
|
||||||
public void handleMessage(Message message) {
|
public void handleMessage(Message message) {
|
||||||
// handle messages by standard KeychainIntentServiceHandler first
|
// handle messages by standard KeychainIntentServiceHandler first
|
||||||
super.handleMessage(message);
|
super.handleMessage(message);
|
||||||
|
@ -192,6 +192,7 @@ public class LogDisplayFragment extends ListFragment implements OnTouchListener
|
|||||||
case ERROR: ih.mImg.setBackgroundColor(Color.RED); break;
|
case ERROR: ih.mImg.setBackgroundColor(Color.RED); break;
|
||||||
case START: ih.mImg.setBackgroundColor(Color.GREEN); break;
|
case START: ih.mImg.setBackgroundColor(Color.GREEN); break;
|
||||||
case OK: ih.mImg.setBackgroundColor(Color.GREEN); break;
|
case OK: ih.mImg.setBackgroundColor(Color.GREEN); break;
|
||||||
|
case CANCELLED: ih.mImg.setBackgroundColor(Color.RED); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertView;
|
return convertView;
|
||||||
|
@ -21,32 +21,29 @@ import android.app.Activity;
|
|||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.DialogInterface.OnCancelListener;
|
|
||||||
import android.content.DialogInterface.OnKeyListener;
|
import android.content.DialogInterface.OnKeyListener;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
import android.view.ContextThemeWrapper;
|
import android.view.ContextThemeWrapper;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.widget.Button;
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.service.KeychainIntentService;
|
||||||
|
|
||||||
public class ProgressDialogFragment extends DialogFragment {
|
public class ProgressDialogFragment extends DialogFragment {
|
||||||
private static final String ARG_MESSAGE = "message";
|
private static final String ARG_MESSAGE = "message";
|
||||||
private static final String ARG_STYLE = "style";
|
private static final String ARG_STYLE = "style";
|
||||||
private static final String ARG_CANCELABLE = "cancelable";
|
private static final String ARG_CANCELABLE = "cancelable";
|
||||||
|
|
||||||
private OnCancelListener mOnCancelListener;
|
boolean mCanCancel = false, mPreventCancel = false, mIsCancelled = false;
|
||||||
|
|
||||||
/**
|
/** Creates new instance of this fragment */
|
||||||
* Creates new instance of this fragment
|
public static ProgressDialogFragment newInstance(String message, int style, boolean cancelable) {
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
* @param style
|
|
||||||
* @param cancelable
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static ProgressDialogFragment newInstance(String message, int style, boolean cancelable,
|
|
||||||
OnCancelListener onCancelListener) {
|
|
||||||
ProgressDialogFragment frag = new ProgressDialogFragment();
|
ProgressDialogFragment frag = new ProgressDialogFragment();
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putString(ARG_MESSAGE, message);
|
args.putString(ARG_MESSAGE, message);
|
||||||
@ -54,43 +51,33 @@ public class ProgressDialogFragment extends DialogFragment {
|
|||||||
args.putBoolean(ARG_CANCELABLE, cancelable);
|
args.putBoolean(ARG_CANCELABLE, cancelable);
|
||||||
|
|
||||||
frag.setArguments(args);
|
frag.setArguments(args);
|
||||||
frag.mOnCancelListener = onCancelListener;
|
|
||||||
|
|
||||||
return frag;
|
return frag;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Updates progress of dialog */
|
||||||
* Updates progress of dialog
|
|
||||||
*
|
|
||||||
* @param messageId
|
|
||||||
* @param progress
|
|
||||||
* @param max
|
|
||||||
*/
|
|
||||||
public void setProgress(int messageId, int progress, int max) {
|
public void setProgress(int messageId, int progress, int max) {
|
||||||
setProgress(getString(messageId), progress, max);
|
setProgress(getString(messageId), progress, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Updates progress of dialog */
|
||||||
* Updates progress of dialog
|
|
||||||
*
|
|
||||||
* @param progress
|
|
||||||
* @param max
|
|
||||||
*/
|
|
||||||
public void setProgress(int progress, int max) {
|
public void setProgress(int progress, int max) {
|
||||||
|
if (mIsCancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ProgressDialog dialog = (ProgressDialog) getDialog();
|
ProgressDialog dialog = (ProgressDialog) getDialog();
|
||||||
|
|
||||||
dialog.setProgress(progress);
|
dialog.setProgress(progress);
|
||||||
dialog.setMax(max);
|
dialog.setMax(max);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Updates progress of dialog */
|
||||||
* Updates progress of dialog
|
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
* @param progress
|
|
||||||
* @param max
|
|
||||||
*/
|
|
||||||
public void setProgress(String message, int progress, int max) {
|
public void setProgress(String message, int progress, int max) {
|
||||||
|
if (mIsCancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ProgressDialog dialog = (ProgressDialog) getDialog();
|
ProgressDialog dialog = (ProgressDialog) getDialog();
|
||||||
|
|
||||||
dialog.setMessage(message);
|
dialog.setMessage(message);
|
||||||
@ -98,15 +85,6 @@ public class ProgressDialogFragment extends DialogFragment {
|
|||||||
dialog.setMax(max);
|
dialog.setMax(max);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel(DialogInterface dialog) {
|
|
||||||
super.onCancel(dialog);
|
|
||||||
|
|
||||||
if (this.mOnCancelListener != null) {
|
|
||||||
this.mOnCancelListener.onCancel(dialog);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates dialog
|
* Creates dialog
|
||||||
*/
|
*/
|
||||||
@ -121,41 +99,88 @@ public class ProgressDialogFragment extends DialogFragment {
|
|||||||
|
|
||||||
ProgressDialog dialog = new ProgressDialog(context);
|
ProgressDialog dialog = new ProgressDialog(context);
|
||||||
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||||
|
// We never use the builtin cancel method
|
||||||
dialog.setCancelable(false);
|
dialog.setCancelable(false);
|
||||||
dialog.setCanceledOnTouchOutside(false);
|
dialog.setCanceledOnTouchOutside(false);
|
||||||
|
|
||||||
String message = getArguments().getString(ARG_MESSAGE);
|
String message = getArguments().getString(ARG_MESSAGE);
|
||||||
int style = getArguments().getInt(ARG_STYLE);
|
int style = getArguments().getInt(ARG_STYLE);
|
||||||
boolean cancelable = getArguments().getBoolean(ARG_CANCELABLE);
|
mCanCancel = getArguments().getBoolean(ARG_CANCELABLE);
|
||||||
|
|
||||||
dialog.setMessage(message);
|
dialog.setMessage(message);
|
||||||
dialog.setProgressStyle(style);
|
dialog.setProgressStyle(style);
|
||||||
|
|
||||||
if (cancelable) {
|
// If this is supposed to be cancelable, add our (custom) cancel mechanic
|
||||||
|
if (mCanCancel) {
|
||||||
|
// Just show the button, take care of the onClickListener afterwards (in onStart)
|
||||||
dialog.setButton(DialogInterface.BUTTON_NEGATIVE,
|
dialog.setButton(DialogInterface.BUTTON_NEGATIVE,
|
||||||
activity.getString(R.string.progress_cancel),
|
activity.getString(R.string.progress_cancel), (DialogInterface.OnClickListener) null);
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
dialog.cancel();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable the back button
|
// Disable the back button regardless
|
||||||
OnKeyListener keyListener = new OnKeyListener() {
|
OnKeyListener keyListener = new OnKeyListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||||
|
if (mCanCancel) {
|
||||||
|
((ProgressDialog) dialog).getButton(
|
||||||
|
DialogInterface.BUTTON_NEGATIVE).performClick();
|
||||||
|
}
|
||||||
|
// return true, indicating we handled this
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
dialog.setOnKeyListener(keyListener);
|
dialog.setOnKeyListener(keyListener);
|
||||||
|
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPreventCancel(boolean preventCancel) {
|
||||||
|
// Don't care if we can't cancel anymore either way!
|
||||||
|
if (mIsCancelled || ! mCanCancel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPreventCancel = preventCancel;
|
||||||
|
final Button negative = ((ProgressDialog) getDialog()).getButton(DialogInterface.BUTTON_NEGATIVE);
|
||||||
|
negative.setVisibility(preventCancel ? View.GONE : View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
// Override the default behavior so the dialog is NOT dismissed on click
|
||||||
|
final Button negative = ((ProgressDialog) getDialog()).getButton(DialogInterface.BUTTON_NEGATIVE);
|
||||||
|
negative.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
// nvm if we are already cancelled, or weren't able to begin with
|
||||||
|
if (mIsCancelled || ! mCanCancel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember this, and don't allow another click
|
||||||
|
mIsCancelled = true;
|
||||||
|
negative.setClickable(false);
|
||||||
|
negative.setTextColor(Color.GRAY);
|
||||||
|
|
||||||
|
// Set the progress bar accordingly
|
||||||
|
ProgressDialog dialog = (ProgressDialog) getDialog();
|
||||||
|
dialog.setIndeterminate(true);
|
||||||
|
dialog.setMessage(getString(R.string.progress_cancelling));
|
||||||
|
|
||||||
|
// send a cancel message. note that this message will be handled by
|
||||||
|
// KeychainIntentService.onStartCommand, which runs in this thread,
|
||||||
|
// not the service one, and will not queue up a command.
|
||||||
|
Intent intent = new Intent(getActivity(), KeychainIntentService.class);
|
||||||
|
intent.setAction(KeychainIntentService.ACTION_CANCEL);
|
||||||
|
getActivity().startService(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.v4.widget.FixedDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.v4.widget.FixedDrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:id="@+id/drawer_layout"
|
android:id="@+id/drawer_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fillViewport="true">
|
android:fillViewport="true">
|
||||||
|
@ -443,7 +443,7 @@
|
|||||||
<!--Consolidate-->
|
<!--Consolidate-->
|
||||||
<!--PassphraseCache-->
|
<!--PassphraseCache-->
|
||||||
<!--unsorted-->
|
<!--unsorted-->
|
||||||
<string name="internal_error">Interner Fehler!</string>
|
<string name="msg_internal_error">Interner Fehler!</string>
|
||||||
<string name="section_certifier_id">Beglaubiger</string>
|
<string name="section_certifier_id">Beglaubiger</string>
|
||||||
<string name="section_cert">Zertifikatdetails</string>
|
<string name="section_cert">Zertifikatdetails</string>
|
||||||
<string name="label_user_id">Identität</string>
|
<string name="label_user_id">Identität</string>
|
||||||
|
@ -662,7 +662,7 @@
|
|||||||
<string name="passp_cache_notif_clear">Limpiar caché</string>
|
<string name="passp_cache_notif_clear">Limpiar caché</string>
|
||||||
<string name="passp_cache_notif_pwd">Contraseña</string>
|
<string name="passp_cache_notif_pwd">Contraseña</string>
|
||||||
<!--unsorted-->
|
<!--unsorted-->
|
||||||
<string name="internal_error">¡Error interno!</string>
|
<string name="msg_internal_error">¡Error interno!</string>
|
||||||
<string name="section_certifier_id">Certificador</string>
|
<string name="section_certifier_id">Certificador</string>
|
||||||
<string name="section_cert">Detalles del certificado</string>
|
<string name="section_cert">Detalles del certificado</string>
|
||||||
<string name="label_user_id">Identidad</string>
|
<string name="label_user_id">Identidad</string>
|
||||||
|
@ -662,7 +662,7 @@
|
|||||||
<string name="passp_cache_notif_clear">Effacer le cache</string>
|
<string name="passp_cache_notif_clear">Effacer le cache</string>
|
||||||
<string name="passp_cache_notif_pwd">Mot de passe</string>
|
<string name="passp_cache_notif_pwd">Mot de passe</string>
|
||||||
<!--unsorted-->
|
<!--unsorted-->
|
||||||
<string name="internal_error">Erreur interne !</string>
|
<string name="msg_internal_error">Erreur interne !</string>
|
||||||
<string name="section_certifier_id">Certificateur</string>
|
<string name="section_certifier_id">Certificateur</string>
|
||||||
<string name="section_cert">Détails du certificat</string>
|
<string name="section_cert">Détails du certificat</string>
|
||||||
<string name="label_user_id">identité</string>
|
<string name="label_user_id">identité</string>
|
||||||
|
@ -662,7 +662,7 @@
|
|||||||
<string name="passp_cache_notif_clear">Pulisci Cache</string>
|
<string name="passp_cache_notif_clear">Pulisci Cache</string>
|
||||||
<string name="passp_cache_notif_pwd">Password</string>
|
<string name="passp_cache_notif_pwd">Password</string>
|
||||||
<!--unsorted-->
|
<!--unsorted-->
|
||||||
<string name="internal_error">Errore interno!</string>
|
<string name="msg_internal_error">Errore interno!</string>
|
||||||
<string name="section_certifier_id">Certificatore</string>
|
<string name="section_certifier_id">Certificatore</string>
|
||||||
<string name="section_cert">Dettagli Certificato</string>
|
<string name="section_cert">Dettagli Certificato</string>
|
||||||
<string name="label_user_id">Identit</string>
|
<string name="label_user_id">Identit</string>
|
||||||
|
@ -637,7 +637,7 @@
|
|||||||
<string name="passp_cache_notif_clear">キャッシュクリア</string>
|
<string name="passp_cache_notif_clear">キャッシュクリア</string>
|
||||||
<string name="passp_cache_notif_pwd">パスワード</string>
|
<string name="passp_cache_notif_pwd">パスワード</string>
|
||||||
<!--unsorted-->
|
<!--unsorted-->
|
||||||
<string name="internal_error">内部エラー!</string>
|
<string name="msg_internal_error">内部エラー!</string>
|
||||||
<string name="section_certifier_id">検証者</string>
|
<string name="section_certifier_id">検証者</string>
|
||||||
<string name="section_cert">証明の詳細</string>
|
<string name="section_cert">証明の詳細</string>
|
||||||
<string name="label_user_id">ユーザID</string>
|
<string name="label_user_id">ユーザID</string>
|
||||||
|
@ -601,7 +601,7 @@
|
|||||||
<string name="passp_cache_notif_clear">Очистити кеш</string>
|
<string name="passp_cache_notif_clear">Очистити кеш</string>
|
||||||
<string name="passp_cache_notif_pwd">Пароль</string>
|
<string name="passp_cache_notif_pwd">Пароль</string>
|
||||||
<!--unsorted-->
|
<!--unsorted-->
|
||||||
<string name="internal_error">Внутрішня помилка!</string>
|
<string name="msg_internal_error">Внутрішня помилка!</string>
|
||||||
<string name="section_certifier_id">Ким підписаний</string>
|
<string name="section_certifier_id">Ким підписаний</string>
|
||||||
<string name="section_cert">Дані сертифікату</string>
|
<string name="section_cert">Дані сертифікату</string>
|
||||||
<string name="label_user_id">Сутність</string>
|
<string name="label_user_id">Сутність</string>
|
||||||
|
@ -262,6 +262,7 @@
|
|||||||
<!-- progress dialogs, usually ending in '…' -->
|
<!-- progress dialogs, usually ending in '…' -->
|
||||||
<string name="progress_done">Done.</string>
|
<string name="progress_done">Done.</string>
|
||||||
<string name="progress_cancel">Cancel</string>
|
<string name="progress_cancel">Cancel</string>
|
||||||
|
<string name="progress_cancelling">cancelling…</string>
|
||||||
<string name="progress_saving">saving…</string>
|
<string name="progress_saving">saving…</string>
|
||||||
<string name="progress_importing">importing…</string>
|
<string name="progress_importing">importing…</string>
|
||||||
<string name="progress_exporting">exporting…</string>
|
<string name="progress_exporting">exporting…</string>
|
||||||
@ -381,8 +382,10 @@
|
|||||||
</plurals>
|
</plurals>
|
||||||
<string name="view_log">View Log</string>
|
<string name="view_log">View Log</string>
|
||||||
<string name="import_error_nothing">Nothing to import.</string>
|
<string name="import_error_nothing">Nothing to import.</string>
|
||||||
|
<string name="import_error_nothing_cancelled">Import cancelled.</string>
|
||||||
<string name="import_error">Error importing keys!</string>
|
<string name="import_error">Error importing keys!</string>
|
||||||
<string name="import_with_warnings">, with warnings</string>
|
<string name="import_with_warnings">, with warnings</string>
|
||||||
|
<string name="import_with_cancelled">, until cancelled</string>
|
||||||
|
|
||||||
<!-- Intent labels -->
|
<!-- Intent labels -->
|
||||||
<string name="intent_decrypt_file">Decrypt File with OpenKeychain</string>
|
<string name="intent_decrypt_file">Decrypt File with OpenKeychain</string>
|
||||||
@ -519,6 +522,9 @@
|
|||||||
|
|
||||||
<!-- LogType log messages. Errors should have _ERROR_ in their name and end with a ! -->
|
<!-- LogType log messages. Errors should have _ERROR_ in their name and end with a ! -->
|
||||||
|
|
||||||
|
<string name="msg_internal_error">Internal error!</string>
|
||||||
|
<string name="msg_cancelled">Operation cancelled.</string>
|
||||||
|
|
||||||
<!-- Import Public log entries -->
|
<!-- Import Public log entries -->
|
||||||
<string name="msg_ip_apply_batch">Applying insert batch operation.</string>
|
<string name="msg_ip_apply_batch">Applying insert batch operation.</string>
|
||||||
<string name="msg_ip_bad_type_secret">Tried to import secret keyring as public. This is a bug, please file a report!</string>
|
<string name="msg_ip_bad_type_secret">Tried to import secret keyring as public. This is a bug, please file a report!</string>
|
||||||
@ -744,7 +750,6 @@
|
|||||||
<string name="passp_cache_notif_pwd">Password</string>
|
<string name="passp_cache_notif_pwd">Password</string>
|
||||||
|
|
||||||
<!-- unsorted -->
|
<!-- unsorted -->
|
||||||
<string name="internal_error">Internal error!</string>
|
|
||||||
<string name="section_certifier_id">Certifier</string>
|
<string name="section_certifier_id">Certifier</string>
|
||||||
<string name="section_cert">Certificate Details</string>
|
<string name="section_cert">Certificate Details</string>
|
||||||
<string name="label_user_id">Identity</string>
|
<string name="label_user_id">Identity</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user