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

Commit 6ceec725 authored by Vincent Breitmoser's avatar Vincent Breitmoser Committed by Vincent Breitmoser
Browse files

messageview: use memory-backed body for decrpyted parts which are small and not attachments

parent a55db0f3
Loading
Loading
Loading
Loading
+65 −6
Original line number Diff line number Diff line
package com.fsck.k9.mailstore;


import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -8,13 +9,23 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.support.annotation.Nullable;
import android.util.Log;

import com.fsck.k9.K9;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.internet.SizeAware;

import org.apache.commons.io.output.DeferredFileOutputStream;

public class DecryptedTempFileBody extends BinaryAttachmentBody implements SizeAware {
    public static final int MEMORY_BACKED_THRESHOLD = 1024 * 8;


    private final File tempDirectory;
    @Nullable
    private File file;
    @Nullable
    private byte[] data;


    public DecryptedTempFileBody(File tempDirectory, String transferEncoding) {
@@ -27,14 +38,33 @@ public class DecryptedTempFileBody extends BinaryAttachmentBody implements SizeA
    }

    public OutputStream getOutputStream() throws IOException {
        file = File.createTempFile("decrypted", null, tempDirectory);
        return new FileOutputStream(file);
        return new DeferredFileOutputStream(MEMORY_BACKED_THRESHOLD, "decrypted", null, tempDirectory) {
            @Override
            public void close() throws IOException {
                super.close();

                if (isThresholdExceeded()) {
                    file = getFile();
                } else {
                    data = getData();
                }
            }
        };
    }

    @Override
    public InputStream getInputStream() throws MessagingException {
        try {
            if (file != null) {
                Log.d(K9.LOG_TAG, "Decrypted data is file-backed.");
                return new FileInputStream(file);
            }
            if (data != null) {
                Log.d(K9.LOG_TAG, "Decrypted data is memory-backed.");
                return new ByteArrayInputStream(data);
            }

            throw new IllegalStateException("Data must be fully written before it can be read!");
        } catch (IOException ioe) {
            throw new MessagingException("Unable to open body", ioe);
        }
@@ -42,10 +72,39 @@ public class DecryptedTempFileBody extends BinaryAttachmentBody implements SizeA

    @Override
    public long getSize() {
        if (file != null) {
            return file.length();
        }
        if (data != null) {
            return data.length;
        }

    public File getFile() {
        throw new IllegalStateException("Data must be fully written before it can be read!");
    }

    public File getFile() throws IOException {
        if (file == null) {
            writeMemoryToFile();
        }
        return file;
    }

    private void writeMemoryToFile() throws IOException {
        if (file != null) {
            throw new IllegalStateException("Body is already file-backed!");
        }
        if (data == null) {
            throw new IllegalStateException("Data must be fully written before it can be read!");
        }

        Log.d(K9.LOG_TAG, "Writing body to file for attachment access");

        file = File.createTempFile("decrypted", null, tempDirectory);

        FileOutputStream fos = new FileOutputStream(file);
        fos.write(data);
        fos.close();

        data = null;
    }
}
+9 −4
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ package com.fsck.k9.message.extractors;


import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@@ -45,14 +46,18 @@ public class AttachmentInfoExtractor {
            Body body = part.getBody();
            if (body instanceof DecryptedTempFileBody) {
                DecryptedTempFileBody decryptedTempFileBody = (DecryptedTempFileBody) body;
                try {
                    size = decryptedTempFileBody.getSize();

                    File file = decryptedTempFileBody.getFile();
                    uri = K9FileProvider.getUriForFile(context, file, part.getMimeType());
                } catch (IOException e) {
                    throw new MessagingException("Error preparing decrypted data as attachment", e);
                }

                return extractAttachmentInfo(part, uri, size);
            } else {
                throw new RuntimeException("Not supported");
                throw new UnsupportedOperationException();
            }
        }