Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68e31a98 authored by Vincent Breitmoser's avatar Vincent Breitmoser Committed by Vincent Breitmoser
Browse files

messageview: cancel operation when fragment is destroyed

parent 9b1e51c5
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -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;
+10 −0
Original line number Diff line number Diff line
@@ -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);

+53 −6
Original line number Diff line number Diff line
@@ -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;
+4 −12
Original line number Diff line number Diff line
@@ -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);
                }