mirror of
https://github.com/thunderbird/thunderbird-android.git
synced 2024-09-20 12:12:15 +02:00
messageview: cancel operation when fragment is destroyed
This commit is contained in:
parent
9b1e51c559
commit
68e31a985f
@ -42,6 +42,7 @@ import org.openintents.openpgp.OpenPgpDecryptionResult;
|
||||
import org.openintents.openpgp.OpenPgpError;
|
||||
import org.openintents.openpgp.OpenPgpSignatureResult;
|
||||
import org.openintents.openpgp.util.OpenPgpApi;
|
||||
import org.openintents.openpgp.util.OpenPgpApi.CancelableBackgroundOperation;
|
||||
import org.openintents.openpgp.util.OpenPgpApi.IOpenPgpSinkResultCallback;
|
||||
import org.openintents.openpgp.util.OpenPgpApi.OpenPgpDataSink;
|
||||
import org.openintents.openpgp.util.OpenPgpApi.OpenPgpDataSource;
|
||||
@ -69,6 +70,8 @@ public class MessageCryptoHelper {
|
||||
private Intent userInteractionResultIntent;
|
||||
private LocalMessage currentMessage;
|
||||
private boolean secondPassStarted;
|
||||
private CancelableBackgroundOperation cancelableBackgroundOperation;
|
||||
private boolean isCancelled;
|
||||
|
||||
|
||||
public MessageCryptoHelper(Activity activity, Account account, MessageCryptoCallback callback) {
|
||||
@ -151,6 +154,10 @@ public class MessageCryptoHelper {
|
||||
}
|
||||
|
||||
private void decryptOrVerifyNextPart() {
|
||||
if (isCancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (partsToDecryptOrVerify.isEmpty()) {
|
||||
runSecondPassOrReturnResultToFragment();
|
||||
return;
|
||||
@ -232,7 +239,8 @@ public class MessageCryptoHelper {
|
||||
OpenPgpDataSource dataSource = getDataSourceForEncryptedOrInlineData();
|
||||
OpenPgpDataSink<MimeBodyPart> dataSink = getDataSinkForDecryptedInlineData();
|
||||
|
||||
openPgpApi.executeApiAsync(intent, dataSource, dataSink, new IOpenPgpSinkResultCallback<MimeBodyPart>() {
|
||||
cancelableBackgroundOperation = openPgpApi.executeApiAsync(intent, dataSource, dataSink,
|
||||
new IOpenPgpSinkResultCallback<MimeBodyPart>() {
|
||||
@Override
|
||||
public void onProgress(int current, int max) {
|
||||
Log.d(K9.LOG_TAG, "received progress status: " + current + " / " + max);
|
||||
@ -247,6 +255,13 @@ public class MessageCryptoHelper {
|
||||
});
|
||||
}
|
||||
|
||||
public void cancelIfRunning() {
|
||||
isCancelled = true;
|
||||
if (cancelableBackgroundOperation != null) {
|
||||
cancelableBackgroundOperation.cancelOperation();
|
||||
}
|
||||
}
|
||||
|
||||
private OpenPgpDataSink<MimeBodyPart> getDataSinkForDecryptedInlineData() {
|
||||
return new OpenPgpDataSink<MimeBodyPart>() {
|
||||
@Override
|
||||
@ -269,7 +284,8 @@ public class MessageCryptoHelper {
|
||||
OpenPgpDataSource dataSource = getDataSourceForEncryptedOrInlineData();
|
||||
OpenPgpDataSink<MimeBodyPart> openPgpDataSink = getDataSinkForDecryptedData();
|
||||
|
||||
openPgpApi.executeApiAsync(intent, dataSource, openPgpDataSink, new IOpenPgpSinkResultCallback<MimeBodyPart>() {
|
||||
cancelableBackgroundOperation = openPgpApi.executeApiAsync(intent, dataSource, openPgpDataSink,
|
||||
new IOpenPgpSinkResultCallback<MimeBodyPart>() {
|
||||
@Override
|
||||
public void onReturn(Intent result, MimeBodyPart decryptedPart) {
|
||||
currentCryptoResult = result;
|
||||
@ -462,6 +478,10 @@ public class MessageCryptoHelper {
|
||||
}
|
||||
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (isCancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestCode != REQUEST_CODE_USER_INTERACTION) {
|
||||
throw new IllegalStateException("got an activity result that wasn't meant for us. this is a bug!");
|
||||
}
|
||||
@ -526,7 +546,6 @@ public class MessageCryptoHelper {
|
||||
callback.onCryptoOperationsFinished(messageAnnotations);
|
||||
}
|
||||
|
||||
|
||||
private static class CryptoPart {
|
||||
public final CryptoPartType type;
|
||||
public final Part part;
|
||||
|
@ -19,6 +19,7 @@ import android.content.Loader;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.ContextThemeWrapper;
|
||||
@ -144,6 +145,14 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void cancelAndClearMessageCryptoHelper() {
|
||||
if (messageCryptoHelper != null) {
|
||||
messageCryptoHelper.cancelIfRunning();
|
||||
messageCryptoHelper = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
@ -233,6 +242,7 @@ public class MessageViewFragment extends Fragment implements ConfirmationDialogF
|
||||
getLoaderManager().initLoader(LOCAL_MESSAGE_LOADER_ID, null, localMessageLoaderCallback);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void onLoadMessageFromDatabaseFinished(LocalMessage message) {
|
||||
displayMessageHeader(message);
|
||||
|
||||
|
@ -35,6 +35,7 @@ import android.util.Log;
|
||||
import org.openintents.openpgp.IOpenPgpService2;
|
||||
import org.openintents.openpgp.OpenPgpError;
|
||||
import org.openintents.openpgp.util.ParcelFileDescriptorUtil.DataSinkTransferThread;
|
||||
import org.openintents.openpgp.util.ParcelFileDescriptorUtil.DataSourceTransferThread;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ -288,7 +289,12 @@ public class OpenPgpApi {
|
||||
void onReturn(final Intent result, T sinkResult);
|
||||
}
|
||||
|
||||
private class OpenPgpSourceSinkAsyncTask<T> extends AsyncTask<Void, Integer, OpenPgpDataResult<T>> {
|
||||
public interface CancelableBackgroundOperation {
|
||||
void cancelOperation();
|
||||
}
|
||||
|
||||
private class OpenPgpSourceSinkAsyncTask<T> extends AsyncTask<Void, Integer, OpenPgpDataResult<T>>
|
||||
implements CancelableBackgroundOperation {
|
||||
Intent data;
|
||||
OpenPgpDataSource dataSource;
|
||||
OpenPgpDataSink<T> dataSink;
|
||||
@ -310,6 +316,14 @@ public class OpenPgpApi {
|
||||
protected void onPostExecute(OpenPgpDataResult<T> result) {
|
||||
callback.onReturn(result.apiResult, result.sinkResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelOperation() {
|
||||
cancel(true);
|
||||
if (dataSource != null) {
|
||||
dataSource.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class OpenPgpAsyncTask extends AsyncTask<Void, Integer, Intent> {
|
||||
@ -335,8 +349,8 @@ public class OpenPgpApi {
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void executeApiAsync(Intent data, OpenPgpDataSource dataSource, OpenPgpDataSink<T> dataSink,
|
||||
final IOpenPgpSinkResultCallback<T> callback) {
|
||||
public <T> CancelableBackgroundOperation executeApiAsync(Intent data, OpenPgpDataSource dataSource,
|
||||
OpenPgpDataSink<T> dataSink, final IOpenPgpSinkResultCallback<T> callback) {
|
||||
Messenger messenger = new Messenger(new Handler(new Handler.Callback() {
|
||||
@Override
|
||||
public boolean handleMessage(Message message) {
|
||||
@ -356,9 +370,10 @@ public class OpenPgpApi {
|
||||
task.execute((Void[]) null);
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
public void executeApiAsync(Intent data, OpenPgpDataSource dataSource, IOpenPgpSinkResultCallback<Void> callback) {
|
||||
public AsyncTask executeApiAsync(Intent data, OpenPgpDataSource dataSource, IOpenPgpSinkResultCallback<Void> callback) {
|
||||
OpenPgpSourceSinkAsyncTask<Void> task = new OpenPgpSourceSinkAsyncTask<>(data, dataSource, null, callback);
|
||||
|
||||
// don't serialize async tasks!
|
||||
@ -369,6 +384,7 @@ public class OpenPgpApi {
|
||||
task.execute((Void[]) null);
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
public void executeApiAsync(Intent data, InputStream is, OutputStream os, IOpenPgpCallback callback) {
|
||||
@ -404,7 +420,7 @@ public class OpenPgpApi {
|
||||
} else {
|
||||
data.removeExtra(EXTRA_PROGRESS_MESSENGER);
|
||||
}
|
||||
input = ParcelFileDescriptorUtil.asyncPipeFromDataSource(dataSource);
|
||||
input = dataSource.startPumpThread();
|
||||
}
|
||||
|
||||
DataSinkTransferThread<T> pumpThread = null;
|
||||
@ -487,10 +503,41 @@ public class OpenPgpApi {
|
||||
}
|
||||
|
||||
public static abstract class OpenPgpDataSource {
|
||||
private boolean isCancelled;
|
||||
private ParcelFileDescriptor writeSidePfd;
|
||||
|
||||
|
||||
public abstract void writeTo(OutputStream os) throws IOException;
|
||||
|
||||
public Long getSizeForProgress() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return isCancelled;
|
||||
}
|
||||
|
||||
private ParcelFileDescriptor startPumpThread() throws IOException {
|
||||
if (writeSidePfd != null) {
|
||||
throw new IllegalStateException("startPumpThread() must only be called once!");
|
||||
}
|
||||
ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
|
||||
ParcelFileDescriptor readSidePfd = pipe[0];
|
||||
writeSidePfd = pipe[1];
|
||||
|
||||
new DataSourceTransferThread(this, new ParcelFileDescriptor.AutoCloseOutputStream(writeSidePfd)).start();
|
||||
|
||||
return readSidePfd;
|
||||
}
|
||||
|
||||
private void cancel() {
|
||||
isCancelled = true;
|
||||
try {
|
||||
writeSidePfd.close();
|
||||
} catch (IOException e) {
|
||||
// this is fine
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface OpenPgpDataSink<T> {
|
||||
@ -508,7 +555,7 @@ public class OpenPgpApi {
|
||||
} else {
|
||||
data.removeExtra(EXTRA_PROGRESS_MESSENGER);
|
||||
}
|
||||
input = ParcelFileDescriptorUtil.asyncPipeFromDataSource(dataSource);
|
||||
input = dataSource.startPumpThread();
|
||||
}
|
||||
|
||||
Thread pumpThread = null;
|
||||
|
@ -99,16 +99,6 @@ public class ParcelFileDescriptorUtil {
|
||||
return dataSinkTransferThread;
|
||||
}
|
||||
|
||||
public static ParcelFileDescriptor asyncPipeFromDataSource(OpenPgpDataSource dataSource) throws IOException {
|
||||
ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
|
||||
ParcelFileDescriptor readSide = pipe[0];
|
||||
ParcelFileDescriptor writeSide = pipe[1];
|
||||
|
||||
new DataSourceTransferThread(dataSource, new ParcelFileDescriptor.AutoCloseOutputStream(writeSide)).start();
|
||||
|
||||
return readSide;
|
||||
}
|
||||
|
||||
static class DataSourceTransferThread extends Thread {
|
||||
final OpenPgpDataSource dataSource;
|
||||
final OutputStream outputStream;
|
||||
@ -125,8 +115,10 @@ public class ParcelFileDescriptorUtil {
|
||||
try {
|
||||
dataSource.writeTo(outputStream);
|
||||
} catch (IOException e) {
|
||||
if (isIOExceptionCausedByEPIPE(e)) {
|
||||
Log.e(OpenPgpApi.TAG, "Stopped writing due to broken pipe (other end closed pipe?)");
|
||||
if (dataSource.isCancelled()) {
|
||||
Log.d(OpenPgpApi.TAG, "Stopped writing because operation was cancelled.");
|
||||
} else if (isIOExceptionCausedByEPIPE(e)) {
|
||||
Log.d(OpenPgpApi.TAG, "Stopped writing due to broken pipe (other end closed pipe?)");
|
||||
} else {
|
||||
Log.e(OpenPgpApi.TAG, "IOException when writing to out", e);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user