Use CancellationSignal for cancellation in UI code
This commit is contained in:
@@ -24,6 +24,7 @@ import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.os.CancellationSignal;
|
||||
|
||||
import org.sufficientlysecure.keychain.daos.KeyWritableRepository;
|
||||
import org.sufficientlysecure.keychain.operations.BackupOperation;
|
||||
@@ -64,90 +65,101 @@ public class KeychainServiceTask {
|
||||
private final KeyWritableRepository keyRepository;
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public void startOperationInBackground(
|
||||
public CancellationSignal startOperationInBackground(
|
||||
Parcelable inputParcel, CryptoInputParcel cryptoInput, OperationCallback operationCallback) {
|
||||
new AsyncTask<Void,ProgressUpdate,OperationResult>() {
|
||||
private AtomicBoolean operationCancelledBoolean = new AtomicBoolean(false);
|
||||
AtomicBoolean operationCancelledBoolean = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
protected OperationResult doInBackground(Void... voids) {
|
||||
BaseOperation op;
|
||||
AsyncTask<Void, ProgressUpdate, OperationResult> asyncTask =
|
||||
new AsyncTask<Void, ProgressUpdate, OperationResult>() {
|
||||
@Override
|
||||
protected OperationResult doInBackground(Void... voids) {
|
||||
BaseOperation op;
|
||||
|
||||
if (inputParcel instanceof SignEncryptParcel) {
|
||||
op = new SignEncryptOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof PgpDecryptVerifyInputParcel) {
|
||||
op = new PgpDecryptVerifyOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof SaveKeyringParcel) {
|
||||
op = new EditKeyOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof ChangeUnlockParcel) {
|
||||
op = new ChangeUnlockOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof RevokeKeyringParcel) {
|
||||
op = new RevokeOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof CertifyActionsParcel) {
|
||||
op = new CertifyOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof DeleteKeyringParcel) {
|
||||
op = new DeleteOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof PromoteKeyringParcel) {
|
||||
op = new PromoteKeyOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof ImportKeyringParcel) {
|
||||
op = new ImportOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof BackupKeyringParcel) {
|
||||
op = new BackupOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof UploadKeyringParcel) {
|
||||
op = new UploadOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof KeybaseVerificationParcel) {
|
||||
op = new KeybaseVerificationOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof InputDataParcel) {
|
||||
op = new InputDataOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof BenchmarkInputParcel) {
|
||||
op = new BenchmarkOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof KeySyncParcel) {
|
||||
op = new KeySyncOperation(context, keyRepository, asyncProgressable, operationCancelledBoolean);
|
||||
} else {
|
||||
throw new AssertionError("Unrecognized input parcel in KeychainService!");
|
||||
}
|
||||
if (inputParcel instanceof SignEncryptParcel) {
|
||||
op = new SignEncryptOperation(context, keyRepository, asyncProgressable,
|
||||
operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof PgpDecryptVerifyInputParcel) {
|
||||
op = new PgpDecryptVerifyOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof SaveKeyringParcel) {
|
||||
op = new EditKeyOperation(context, keyRepository, asyncProgressable,
|
||||
operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof ChangeUnlockParcel) {
|
||||
op = new ChangeUnlockOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof RevokeKeyringParcel) {
|
||||
op = new RevokeOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof CertifyActionsParcel) {
|
||||
op = new CertifyOperation(context, keyRepository, asyncProgressable,
|
||||
operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof DeleteKeyringParcel) {
|
||||
op = new DeleteOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof PromoteKeyringParcel) {
|
||||
op = new PromoteKeyOperation(context, keyRepository, asyncProgressable,
|
||||
operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof ImportKeyringParcel) {
|
||||
op = new ImportOperation(context, keyRepository, asyncProgressable,
|
||||
operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof BackupKeyringParcel) {
|
||||
op = new BackupOperation(context, keyRepository, asyncProgressable,
|
||||
operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof UploadKeyringParcel) {
|
||||
op = new UploadOperation(context, keyRepository, asyncProgressable,
|
||||
operationCancelledBoolean);
|
||||
} else if (inputParcel instanceof KeybaseVerificationParcel) {
|
||||
op = new KeybaseVerificationOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof InputDataParcel) {
|
||||
op = new InputDataOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof BenchmarkInputParcel) {
|
||||
op = new BenchmarkOperation(context, keyRepository, asyncProgressable);
|
||||
} else if (inputParcel instanceof KeySyncParcel) {
|
||||
op = new KeySyncOperation(context, keyRepository, asyncProgressable,
|
||||
operationCancelledBoolean);
|
||||
} else {
|
||||
throw new AssertionError("Unrecognized input parcel in KeychainService!");
|
||||
}
|
||||
|
||||
if (isCancelled()) {
|
||||
return null;
|
||||
}
|
||||
if (isCancelled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// noinspection unchecked, we make sure it's the correct op above
|
||||
return op.execute(inputParcel, cryptoInput);
|
||||
}
|
||||
// noinspection unchecked, we make sure it's the correct op above
|
||||
return op.execute(inputParcel, cryptoInput);
|
||||
}
|
||||
|
||||
Progressable asyncProgressable = new Progressable() {
|
||||
@Override
|
||||
public void setPreventCancel() {
|
||||
publishProgress((ProgressUpdate) null);
|
||||
}
|
||||
Progressable asyncProgressable = new Progressable() {
|
||||
@Override
|
||||
public void setPreventCancel() {
|
||||
publishProgress((ProgressUpdate) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgress(Integer resourceId, int current, int total) {
|
||||
publishProgress(new ProgressUpdate(resourceId, current, total));
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void setProgress(Integer resourceId, int current, int total) {
|
||||
publishProgress(new ProgressUpdate(resourceId, current, total));
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(ProgressUpdate... values) {
|
||||
ProgressUpdate progressUpdate = values[0];
|
||||
if (progressUpdate == null) {
|
||||
operationCallback.setPreventCancel();
|
||||
} else {
|
||||
operationCallback.setProgress(progressUpdate.resourceId, progressUpdate.current, progressUpdate.total);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onProgressUpdate(ProgressUpdate... values) {
|
||||
ProgressUpdate progressUpdate = values[0];
|
||||
if (progressUpdate == null) {
|
||||
operationCallback.setPreventCancel();
|
||||
} else {
|
||||
operationCallback.setProgress(progressUpdate.resourceId, progressUpdate.current,
|
||||
progressUpdate.total);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancelled() {
|
||||
super.onCancelled();
|
||||
operationCancelledBoolean.set(true);
|
||||
}
|
||||
@Override
|
||||
protected void onPostExecute(OperationResult result) {
|
||||
operationCallback.operationFinished(result);
|
||||
}
|
||||
};
|
||||
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(OperationResult result) {
|
||||
operationCallback.operationFinished(result);
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
CancellationSignal cancellationSignal = new CancellationSignal();
|
||||
cancellationSignal.setOnCancelListener(() -> {
|
||||
operationCancelledBoolean.set(true);
|
||||
});
|
||||
return cancellationSignal;
|
||||
}
|
||||
|
||||
public interface OperationCallback {
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.app.ProgressDialog;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.os.CancellationSignal;
|
||||
|
||||
import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment;
|
||||
|
||||
@@ -36,16 +37,16 @@ public class ProgressDialogManager {
|
||||
}
|
||||
|
||||
public void showProgressDialog() {
|
||||
showProgressDialog("", ProgressDialog.STYLE_SPINNER, false);
|
||||
showProgressDialog("", ProgressDialog.STYLE_SPINNER, null);
|
||||
}
|
||||
|
||||
public void showProgressDialog(
|
||||
String progressDialogMessage, int progressDialogStyle, boolean cancelable) {
|
||||
String progressDialogMessage, int progressDialogStyle, CancellationSignal cancellationSignal) {
|
||||
|
||||
final ProgressDialogFragment frag = ProgressDialogFragment.newInstance(
|
||||
progressDialogMessage,
|
||||
progressDialogStyle,
|
||||
cancelable);
|
||||
progressDialogMessage, progressDialogStyle, cancellationSignal != null);
|
||||
|
||||
frag.setCancellationSignal(cancellationSignal);
|
||||
|
||||
// TODO: This is a hack!, see
|
||||
// http://stackoverflow.com/questions/10114324/show-dialogfragment-from-onactivityresult
|
||||
@@ -79,9 +80,7 @@ public class ProgressDialogManager {
|
||||
progressDialogFragment.dismissAllowingStateLoss();
|
||||
}
|
||||
|
||||
|
||||
public void onSetProgress(Integer resourceInt, int progress, int max) {
|
||||
|
||||
ProgressDialogFragment progressDialogFragment =
|
||||
(ProgressDialogFragment) activity.getSupportFragmentManager()
|
||||
.findFragmentByTag(TAG_PROGRESS_DIALOG);
|
||||
@@ -95,7 +94,5 @@ public class ProgressDialogManager {
|
||||
} else {
|
||||
progressDialogFragment.setProgress(progress, max);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user