messageview: use memory-backed body for decrpyted parts which are small and not attachments
This commit is contained in:
parent
a55db0f3cf
commit
6ceec725cb
2 changed files with 74 additions and 10 deletions
|
@ -1,6 +1,7 @@
|
|||
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 {
|
||||
return new FileInputStream(file);
|
||||
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() {
|
||||
return file.length();
|
||||
if (file != null) {
|
||||
return file.length();
|
||||
}
|
||||
if (data != null) {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Data must be fully written before it can be read!");
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
size = decryptedTempFileBody.getSize();
|
||||
try {
|
||||
size = decryptedTempFileBody.getSize();
|
||||
|
||||
File file = decryptedTempFileBody.getFile();
|
||||
uri = K9FileProvider.getUriForFile(context, file, part.getMimeType());
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue