Delete attachments when necessary, don't leak disk space

* Add AttachmentProvider.deleteAllMailboxAttachmentFiles
* Call it when server deletes a mailbox
* Confirmed (no change) all message deletes call deleteAllAttachmentFiles
* Unit tests of course :)

Bug # 2069004

Change-Id: I99731e6489fdca4cc9cebdff5fcf9c09d12b7b3a
This commit is contained in:
Andrew Stadler 2009-09-30 23:32:30 -07:00
parent 1e3ac08a3f
commit 71754d3f94
3 changed files with 84 additions and 1 deletions

View File

@ -321,7 +321,11 @@ public class MessagingController implements Runnable {
case Mailbox.TYPE_TRASH:
break;
default:
// TODO drop all attachment files too
// Drop all attachment files related to this mailbox
AttachmentProvider.deleteAllMailboxAttachmentFiles(
mContext, accountId, localInfo.mId);
// Delete the mailbox. Triggers will take care of
// related Message, Body and Attachment records.
Uri uri = ContentUris.withAppendedId(
EmailContent.Mailbox.CONTENT_URI, localInfo.mId);
mContext.getContentResolver().delete(uri, null, null);

View File

@ -19,6 +19,8 @@ package com.android.email.provider;
import com.android.email.mail.internet.MimeUtility;
import com.android.email.provider.EmailContent.Attachment;
import com.android.email.provider.EmailContent.AttachmentColumns;
import com.android.email.provider.EmailContent.Message;
import com.android.email.provider.EmailContent.MessageColumns;
import android.content.ContentProvider;
import android.content.ContentResolver;
@ -376,4 +378,26 @@ public class AttachmentProvider extends ContentProvider {
c.close();
}
}
/**
* In support of deleting a mailbox, find all messages and delete their attachments.
*
* @param context
* @param accountId the account for the mailbox
* @param mailboxId the mailbox for the messages
*/
public static void deleteAllMailboxAttachmentFiles(Context context, long accountId,
long mailboxId) {
Cursor c = context.getContentResolver().query(Message.CONTENT_URI,
Message.ID_COLUMN_PROJECTION, MessageColumns.MAILBOX_KEY + "=?",
new String[] { Long.toString(mailboxId) }, null);
try {
while (c.moveToNext()) {
long messageId = c.getLong(Message.ID_PROJECTION_COLUMN);
deleteAllAttachmentFiles(context, accountId, messageId);
}
} finally {
c.close();
}
}
}

View File

@ -22,6 +22,8 @@ import com.android.email.mail.store.LocalStore;
import com.android.email.provider.AttachmentProvider.AttachmentProviderColumns;
import com.android.email.provider.EmailContent.Account;
import com.android.email.provider.EmailContent.Attachment;
import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.Message;
import android.content.ContentResolver;
import android.content.ContentValues;
@ -464,6 +466,59 @@ public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvide
assertEquals(0, attachmentsDir.listFiles().length);
}
/**
* Test the functionality of deleting an entire mailbox's attachments.
*/
public void testDeleteMailbox() throws IOException {
Account account1 = ProviderTestUtils.setupAccount("attach-mbox-del", false, mMockContext);
account1.mCompatibilityUuid = "test-UUID";
account1.save(mMockContext);
long account1Id = account1.mId;
Mailbox mailbox1 = ProviderTestUtils.setupMailbox("mbox1", account1Id, true, mMockContext);
long mailbox1Id = mailbox1.mId;
Mailbox mailbox2 = ProviderTestUtils.setupMailbox("mbox2", account1Id, true, mMockContext);
long mailbox2Id = mailbox2.mId;
// two messages per mailbox, one w/attachments, one w/o attachments
Message message1a = ProviderTestUtils.setupMessage("msg1a", account1Id, mailbox1Id, false,
true, mMockContext);
Message message1b = ProviderTestUtils.setupMessage("msg1b", account1Id, mailbox1Id, false,
true, mMockContext);
Message message2a = ProviderTestUtils.setupMessage("msg2a", account1Id, mailbox2Id, false,
true, mMockContext);
Message message2b = ProviderTestUtils.setupMessage("msg2b", account1Id, mailbox2Id, false,
true, mMockContext);
// attachments on each of the "a" messages (3 on 1a, 1 on 1b)
Attachment newAttachment1 = ProviderTestUtils.setupAttachment(message1a.mId, "file1", 100,
true, mMockContext);
Attachment newAttachment2 = ProviderTestUtils.setupAttachment(message1a.mId, "file2", 200,
true, mMockContext);
Attachment newAttachment3 = ProviderTestUtils.setupAttachment(message1a.mId, "file3", 100,
true, mMockContext);
Attachment newAttachment4 = ProviderTestUtils.setupAttachment(message2a.mId, "file4", 100,
true, mMockContext);
// Create test files
createAttachmentFile(account1, newAttachment1.mId);
createAttachmentFile(account1, newAttachment2.mId);
createAttachmentFile(account1, newAttachment3.mId);
createAttachmentFile(account1, newAttachment4.mId);
// Confirm four attachment files found
File attachmentsDir = AttachmentProvider.getAttachmentDirectory(mMockContext, account1.mId);
assertEquals(4, attachmentsDir.listFiles().length);
// Command the deletion of mailbox 1 - we should lose 3 attachment files
AttachmentProvider.deleteAllMailboxAttachmentFiles(mMockContext, account1Id, mailbox1Id);
assertEquals(1, attachmentsDir.listFiles().length);
// Command the deletion of mailbox 2 - we should lose 1 attachment file
AttachmentProvider.deleteAllMailboxAttachmentFiles(mMockContext, account1Id, mailbox2Id);
assertEquals(0, attachmentsDir.listFiles().length);
}
/**
* Create an attachment by copying an image resource into a file. Uses "real" resources
* to get a real image from Email