Change AttachmentProvider to use the new database structure

This commit is contained in:
cketti 2015-01-07 02:29:56 +01:00
parent e5f0bec6bc
commit ce862c88f8
2 changed files with 125 additions and 41 deletions

View File

@ -31,8 +31,15 @@ import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchSpecification.Attribute;
import com.fsck.k9.search.SearchSpecification.Searchfield;
import com.fsck.k9.search.SqlQueryBuilder;
import org.apache.james.mime4j.codec.Base64InputStream;
import org.apache.james.mime4j.codec.QuotedPrintableInputStream;
import org.apache.james.mime4j.util.MimeUtil;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
@ -648,7 +655,7 @@ public class LocalStore extends Store implements Serializable {
return null;
}
String name = cursor.getString(0);
int size = cursor.getInt(1);
long size = cursor.getLong(1);
String mimeType = cursor.getString(2);
final AttachmentInfo attachmentInfo = new AttachmentInfo();
@ -664,9 +671,72 @@ public class LocalStore extends Store implements Serializable {
});
}
public InputStream getAttachmentInputStream(final String attachmentId) throws MessagingException {
return database.execute(false, new DbCallback<InputStream>() {
@Override
public InputStream doDbWork(final SQLiteDatabase db) throws WrappedException {
Cursor cursor = db.query("message_parts",
new String[] { "data_location", "data", "encoding" },
"id = ?",
new String[] { attachmentId },
null, null, null);
try {
if (!cursor.moveToFirst()) {
return null;
}
int location = cursor.getInt(0);
String encoding = cursor.getString(2);
InputStream rawInputStream = getRawAttachmentInputStream(cursor, location, attachmentId);
return getDecodingInputStream(rawInputStream, encoding);
} finally {
cursor.close();
}
}
});
}
private InputStream getRawAttachmentInputStream(Cursor cursor, int location, String attachmentId) {
switch (location) {
case DataLocation.IN_DATABASE: {
byte[] data = cursor.getBlob(1);
return new ByteArrayInputStream(data);
}
case DataLocation.ON_DISK: {
File file = getAttachmentFile(attachmentId);
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
throw new WrappedException(e);
}
}
default: {
throw new IllegalStateException("No attachment data available");
}
}
}
private InputStream getDecodingInputStream(InputStream rawInputStream, String encoding) {
if (MimeUtil.ENC_BASE64.equals(encoding)) {
return new Base64InputStream(rawInputStream);
}
if (MimeUtil.ENC_QUOTED_PRINTABLE.equals(encoding)) {
return new QuotedPrintableInputStream(rawInputStream);
}
return rawInputStream;
}
private File getAttachmentFile(String attachmentId) {
final StorageManager storageManager = StorageManager.getInstance(context);
final File attachmentDirectory = storageManager.getAttachmentDirectory(uUid, database.getStorageProviderId());
return new File(attachmentDirectory, attachmentId);
}
public static class AttachmentInfo {
public String name;
public int size; //FIXME: use long
public long size;
public String type;
}

View File

@ -19,7 +19,7 @@ import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.internet.MimeUtility;
import com.fsck.k9.mailstore.LocalStore;
import com.fsck.k9.mailstore.LocalStore.AttachmentInfo;
import com.fsck.k9.mailstore.StorageManager;
import org.openintents.openpgp.util.ParcelFileDescriptorUtil;
import java.io.*;
import java.util.List;
@ -156,8 +156,6 @@ public class AttachmentProvider extends ContentProvider {
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
File file;
List<String> segments = uri.getPathSegments();
String accountUuid = segments.get(0);
String attachmentId = segments.get(1);
@ -167,36 +165,10 @@ public class AttachmentProvider extends ContentProvider {
int width = Integer.parseInt(segments.get(3));
int height = Integer.parseInt(segments.get(4));
file = getThumbnailFile(getContext(), accountUuid, attachmentId);
if (!file.exists()) {
String type = getType(accountUuid, attachmentId, FORMAT_VIEW, null);
try {
FileInputStream in = new FileInputStream(getFile(accountUuid, attachmentId));
try {
Bitmap thumbnail = createThumbnail(type, in);
if (thumbnail != null) {
thumbnail = Bitmap.createScaledBitmap(thumbnail, width, height, true);
FileOutputStream out = new FileOutputStream(file);
try {
thumbnail.compress(Bitmap.CompressFormat.PNG, 100, out);
} finally {
out.close();
}
}
} finally {
try {
in.close();
} catch (Throwable ignore) { /* ignore */ }
}
} catch (IOException ioe) {
return null;
}
}
} else {
file = getFile(accountUuid, attachmentId);
return openThumbnail(accountUuid, attachmentId, width, height);
}
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
return openAttachment(accountUuid, attachmentId);
}
@Override
@ -282,18 +254,60 @@ public class AttachmentProvider extends ContentProvider {
return type;
}
private File getFile(String accountUuid, String id) throws FileNotFoundException {
Account account = Preferences.getPreferences(getContext()).getAccount(accountUuid);
private ParcelFileDescriptor openThumbnail(String accountUuid, String attachmentId, int width, int height)
throws FileNotFoundException {
File attachmentsDir = StorageManager.getInstance(getContext()).getAttachmentDirectory(accountUuid,
account.getLocalStorageProviderId());
File file = new File(attachmentsDir, id);
File file = getThumbnailFile(getContext(), accountUuid, attachmentId);
if (!file.exists()) {
throw new FileNotFoundException(file.getAbsolutePath());
String type = getType(accountUuid, attachmentId, FORMAT_VIEW, null);
try {
InputStream in = getAttachmentInputStream(accountUuid, attachmentId);
try {
Bitmap thumbnail = createThumbnail(type, in);
if (thumbnail != null) {
thumbnail = Bitmap.createScaledBitmap(thumbnail, width, height, true);
FileOutputStream out = new FileOutputStream(file);
try {
thumbnail.compress(Bitmap.CompressFormat.PNG, 100, out);
} finally {
try {
out.close();
} catch (IOException e) {
Log.e(K9.LOG_TAG, "Error saving thumbnail", e);
}
}
}
} finally {
try {
in.close();
} catch (Throwable ignore) { /* ignore */ }
}
} catch (MessagingException e) {
Log.e(K9.LOG_TAG, "Error getting InputStream for attachment", e);
return null;
}
}
return file;
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
}
private ParcelFileDescriptor openAttachment(String accountUuid, String attachmentId) {
try {
InputStream inputStream = getAttachmentInputStream(accountUuid, attachmentId);
return ParcelFileDescriptorUtil.pipeFrom(inputStream, null);
} catch (MessagingException e) {
Log.e(K9.LOG_TAG, "Error getting InputStream for attachment", e);
return null;
} catch (IOException e) {
Log.e(K9.LOG_TAG, "Error creating ParcelFileDescriptor", e);
return null;
}
}
private InputStream getAttachmentInputStream(String accountUuid, String attachmentId) throws MessagingException {
final Account account = Preferences.getPreferences(getContext()).getAccount(accountUuid);
LocalStore localStore = LocalStore.getInstance(account, getContext());
return localStore.getAttachmentInputStream(attachmentId);
}
private Bitmap createThumbnail(String type, InputStream data) {