am 0c4dc851: Harden against crashes caused by account deletes

Merge commit '0c4dc85190028f389f0dcbc3dbed0b344d20a313' into eclair-plus-aosp

* commit '0c4dc85190028f389f0dcbc3dbed0b344d20a313':
  Harden against crashes caused by account deletes
This commit is contained in:
Andrew Stadler 2009-09-16 11:05:35 -07:00 committed by Android Git Automerger
commit 2077e5efa2
6 changed files with 178 additions and 221 deletions

View File

@ -842,55 +842,53 @@ public class Controller {
private class LegacyListener extends MessagingListener {
@Override
public void listFoldersStarted(EmailContent.Account account) {
public void listFoldersStarted(long accountId) {
synchronized (mListeners) {
for (Result l : mListeners) {
l.updateMailboxListCallback(null, account.mId, 0);
l.updateMailboxListCallback(null, accountId, 0);
}
}
}
@Override
public void listFoldersFailed(EmailContent.Account account, String message) {
public void listFoldersFailed(long accountId, String message) {
synchronized (mListeners) {
for (Result l : mListeners) {
l.updateMailboxListCallback(new MessagingException(message), account.mId, 0);
l.updateMailboxListCallback(new MessagingException(message), accountId, 0);
}
}
}
@Override
public void listFoldersFinished(EmailContent.Account account) {
public void listFoldersFinished(long accountId) {
synchronized (mListeners) {
for (Result l : mListeners) {
l.updateMailboxListCallback(null, account.mId, 100);
l.updateMailboxListCallback(null, accountId, 100);
}
}
}
@Override
public void synchronizeMailboxStarted(EmailContent.Account account,
EmailContent.Mailbox folder) {
public void synchronizeMailboxStarted(long accountId, long mailboxId) {
synchronized (mListeners) {
for (Result l : mListeners) {
l.updateMailboxCallback(null, account.mId, folder.mId, 0, 0);
l.updateMailboxCallback(null, accountId, mailboxId, 0, 0);
}
}
}
@Override
public void synchronizeMailboxFinished(EmailContent.Account account,
EmailContent.Mailbox folder, int totalMessagesInMailbox, int numNewMessages) {
public void synchronizeMailboxFinished(long accountId, long mailboxId,
int totalMessagesInMailbox, int numNewMessages) {
synchronized (mListeners) {
for (Result l : mListeners) {
l.updateMailboxCallback(null, account.mId, folder.mId, 100, numNewMessages);
l.updateMailboxCallback(null, accountId, mailboxId, 100, numNewMessages);
}
}
}
@Override
public void synchronizeMailboxFailed(EmailContent.Account account,
EmailContent.Mailbox folder, Exception e) {
public void synchronizeMailboxFailed(long accountId, long mailboxId, Exception e) {
MessagingException me;
if (e instanceof MessagingException) {
me = (MessagingException) e;
@ -899,7 +897,7 @@ public class Controller {
}
synchronized (mListeners) {
for (Result l : mListeners) {
l.updateMailboxCallback(me, account.mId, folder.mId, 0, 0);
l.updateMailboxCallback(me, accountId, mailboxId, 0, 0);
}
}
}

View File

@ -52,48 +52,46 @@ public class GroupMessagingListener extends MessagingListener {
}
@Override
synchronized public void listFoldersStarted(EmailContent.Account account) {
synchronized public void listFoldersStarted(long accountId) {
for (MessagingListener l : mListeners) {
l.listFoldersStarted(account);
l.listFoldersStarted(accountId);
}
}
@Override
synchronized public void listFoldersFailed(EmailContent.Account account, String message) {
synchronized public void listFoldersFailed(long accountId, String message) {
for (MessagingListener l : mListeners) {
l.listFoldersFailed(account, message);
l.listFoldersFailed(accountId, message);
}
}
@Override
synchronized public void listFoldersFinished(EmailContent.Account account) {
synchronized public void listFoldersFinished(long accountId) {
for (MessagingListener l : mListeners) {
l.listFoldersFinished(account);
l.listFoldersFinished(accountId);
}
}
@Override
synchronized public void synchronizeMailboxStarted(EmailContent.Account account,
EmailContent.Mailbox folder) {
synchronized public void synchronizeMailboxStarted(long accountId, long mailboxId) {
for (MessagingListener l : mListeners) {
l.synchronizeMailboxStarted(account, folder);
l.synchronizeMailboxStarted(accountId, mailboxId);
}
}
@Override
synchronized public void synchronizeMailboxFinished(EmailContent.Account account,
EmailContent.Mailbox folder, int totalMessagesInMailbox, int numNewMessages) {
synchronized public void synchronizeMailboxFinished(long accountId, long mailboxId,
int totalMessagesInMailbox, int numNewMessages) {
for (MessagingListener l : mListeners) {
l.synchronizeMailboxFinished(account, folder, totalMessagesInMailbox, numNewMessages);
l.synchronizeMailboxFinished(accountId, mailboxId,
totalMessagesInMailbox, numNewMessages);
}
}
@Override
synchronized public void synchronizeMailboxFailed(EmailContent.Account account,
EmailContent.Mailbox folder,
Exception e) {
synchronized public void synchronizeMailboxFailed(long accountId, long mailboxId, Exception e) {
for (MessagingListener l : mListeners) {
l.synchronizeMailboxFailed(account, folder, e);
l.synchronizeMailboxFailed(accountId, mailboxId, e);
}
}
@ -156,17 +154,10 @@ public class GroupMessagingListener extends MessagingListener {
}
@Override
synchronized public void emptyTrashCompleted(EmailContent.Account account) {
for (MessagingListener l : mListeners) {
l.emptyTrashCompleted(account);
}
}
@Override
synchronized public void messageUidChanged(EmailContent.Account account, String folder,
synchronized public void messageUidChanged(long accountId, long mailboxId,
String oldUid, String newUid) {
for (MessagingListener l : mListeners) {
l.messageUidChanged(account, folder, oldUid, newUid);
l.messageUidChanged(accountId, mailboxId, oldUid, newUid);
}
}

View File

@ -41,7 +41,6 @@ import com.android.email.provider.AttachmentProvider;
import com.android.email.provider.EmailContent;
import com.android.email.provider.EmailContent.Attachment;
import com.android.email.provider.EmailContent.AttachmentColumns;
import com.android.email.provider.EmailContent.Body;
import com.android.email.provider.EmailContent.Mailbox;
import com.android.email.provider.EmailContent.MailboxColumns;
import com.android.email.provider.EmailContent.MessageColumns;
@ -237,10 +236,13 @@ public class MessagingController implements Runnable {
* @param listener
* @throws MessagingException
*/
public void listFolders(long accountId, MessagingListener listener) {
public void listFolders(final long accountId, MessagingListener listener) {
final EmailContent.Account account =
EmailContent.Account.restoreAccountWithId(mContext, accountId);
mListeners.listFoldersStarted(account);
if (account == null) {
return;
}
mListeners.listFoldersStarted(accountId);
put("listFolders", listener, new Runnable() {
public void run() {
Cursor localFolderCursor = null;
@ -310,9 +312,9 @@ public class MessagingController implements Runnable {
box.save(mContext);
}
}
mListeners.listFoldersFinished(account);
mListeners.listFoldersFinished(accountId);
} catch (Exception e) {
mListeners.listFoldersFailed(account, "");
mListeners.listFoldersFailed(accountId, "");
} finally {
if (localFolderCursor != null) {
localFolderCursor.close();
@ -396,55 +398,6 @@ public class MessagingController implements Runnable {
*/
}
/**
* List the local message store for the given folder. This work is done
* synchronously.
*
* @param account
* @param folder
* @param listener
* @throws MessagingException
*/
/*
public void listLocalMessages(final EmailContent.Account account, final String folder,
MessagingListener listener) {
synchronized (mListeners) {
for (MessagingListener l : mListeners) {
l.listLocalMessagesStarted(account, folder);
}
}
try {
Store localStore = Store.getInstance(account.getLocalStoreUri(mContext), mContext,
null);
Folder localFolder = localStore.getFolder(folder);
localFolder.open(OpenMode.READ_WRITE, null);
Message[] localMessages = localFolder.getMessages(null);
ArrayList<Message> messages = new ArrayList<Message>();
for (Message message : localMessages) {
if (!message.isSet(Flag.DELETED)) {
messages.add(message);
}
}
synchronized (mListeners) {
for (MessagingListener l : mListeners) {
l.listLocalMessages(account, folder, messages.toArray(new Message[0]));
}
for (MessagingListener l : mListeners) {
l.listLocalMessagesFinished(account, folder);
}
}
}
catch (Exception e) {
synchronized (mListeners) {
for (MessagingListener l : mListeners) {
l.listLocalMessagesFailed(account, folder, e.getMessage());
}
}
}
}
*/
/**
* Start background synchronization of the specified folder.
* @param account
@ -459,7 +412,7 @@ public class MessagingController implements Runnable {
if (folder.mType == EmailContent.Mailbox.TYPE_OUTBOX) {
return;
}
mListeners.synchronizeMailboxStarted(account, folder);
mListeners.synchronizeMailboxStarted(account.mId, folder.mId);
put("synchronizeMailbox", listener, new Runnable() {
public void run() {
synchronizeMailboxSynchronous(account, folder);
@ -476,7 +429,7 @@ public class MessagingController implements Runnable {
*/
private void synchronizeMailboxSynchronous(final EmailContent.Account account,
final EmailContent.Mailbox folder) {
mListeners.synchronizeMailboxStarted(account, folder);
mListeners.synchronizeMailboxStarted(account.mId, folder.mId);
try {
processPendingActionsSynchronous(account);
@ -494,15 +447,14 @@ public class MessagingController implements Runnable {
results = customSync.SynchronizeMessagesSynchronous(
account, folder, mListeners, mContext);
}
mListeners.synchronizeMailboxFinished(account,
folder,
mListeners.synchronizeMailboxFinished(account.mId, folder.mId,
results.mTotalMessages,
results.mNewMessages);
} catch (MessagingException e) {
if (Email.LOGD) {
Log.v(Email.LOG_TAG, "synchronizeMailbox", e);
}
mListeners.synchronizeMailboxFailed(account, folder, e);
mListeners.synchronizeMailboxFailed(account.mId, folder.mId, e);
}
}
@ -1115,6 +1067,9 @@ public class MessagingController implements Runnable {
try {
EmailContent.Account account =
EmailContent.Account.restoreAccountWithId(mContext, accountId);
if (account == null) {
return;
}
processPendingActionsSynchronous(account);
}
catch (MessagingException me) {
@ -1547,7 +1502,7 @@ public class MessagingController implements Runnable {
String oldUid = localMessage.getUid();
remoteFolder.appendMessages(new Message[] { localMessage });
localFolder.changeUid(localMessage);
mListeners.messageUidChanged(account, folder, oldUid, localMessage.getUid());
// mListeners.messageUidChanged(account.mId, -1 folder.mId, oldUid, localMessage.getUid());
}
else {
/*
@ -1580,7 +1535,7 @@ public class MessagingController implements Runnable {
String oldUid = localMessage.getUid();
remoteFolder.appendMessages(new Message[] { localMessage });
localFolder.changeUid(localMessage);
mListeners.messageUidChanged(account, folder, oldUid, localMessage.getUid());
// mListeners.messageUidChanged(account.mId, folder.mId, oldUid, localMessage.getUid());
remoteMessage.setFlag(Flag.DELETED, true);
}
}
@ -1617,6 +1572,10 @@ public class MessagingController implements Runnable {
EmailContent.Account.restoreAccountWithId(mContext, message.mAccountKey);
EmailContent.Mailbox mailbox =
EmailContent.Mailbox.restoreMailboxWithId(mContext, message.mMailboxKey);
if (account == null || mailbox == null) {
mListeners.loadMessageForViewFailed(messageId, "null account or mailbox");
return;
}
Store remoteStore =
Store.getInstance(account.getStoreUri(mContext), mContext, null);
@ -1694,6 +1653,12 @@ public class MessagingController implements Runnable {
EmailContent.Message.restoreMessageWithId(mContext, messageId);
Attachment attachment =
Attachment.restoreAttachmentWithId(mContext, attachmentId);
if (account == null || mailbox == null || message == null
|| attachment == null) {
mListeners.loadAttachmentFailed(accountId, messageId, attachmentId,
"Account, mailbox, message or attachment are null");
return;
}
Store remoteStore =
Store.getInstance(account.getStoreUri(mContext), mContext, null);
@ -1889,19 +1854,26 @@ public class MessagingController implements Runnable {
// send any pending outbound messages. note, there is a slight race condition
// here if we somehow don't have a sent folder, but this should never happen
// because the call to sendMessage() would have built one previously.
long inboxId = -1;
EmailContent.Account account =
EmailContent.Account.restoreAccountWithId(mContext, accountId);
long sentboxId = Mailbox.findMailboxOfType(mContext, accountId, Mailbox.TYPE_SENT);
if (sentboxId != -1) {
sendPendingMessagesSynchronous(account, sentboxId);
if (account != null) {
long sentboxId = Mailbox.findMailboxOfType(mContext, accountId,
Mailbox.TYPE_SENT);
if (sentboxId != Mailbox.NO_MAILBOX) {
sendPendingMessagesSynchronous(account, sentboxId);
}
// find mailbox # for inbox and sync it.
// TODO we already know this in Controller, can we pass it in?
inboxId = Mailbox.findMailboxOfType(mContext, accountId, Mailbox.TYPE_INBOX);
if (inboxId != Mailbox.NO_MAILBOX) {
EmailContent.Mailbox mailbox =
EmailContent.Mailbox.restoreMailboxWithId(mContext, inboxId);
if (mailbox != null) {
synchronizeMailboxSynchronous(account, mailbox);
}
}
}
// find mailbox # for inbox and sync it.
// TODO we already know this in Controller, can we pass it in?
long inboxId = Mailbox.findMailboxOfType(mContext, accountId, Mailbox.TYPE_INBOX);
EmailContent.Mailbox mailbox =
EmailContent.Mailbox.restoreMailboxWithId(mContext, inboxId);
synchronizeMailboxSynchronous(account, mailbox);
mListeners.checkMailFinished(mContext, accountId, tag, inboxId);
}
});

View File

@ -29,24 +29,24 @@ import android.content.Context;
* changes in this class.
*/
public class MessagingListener {
public void listFoldersStarted(EmailContent.Account account) {
public void listFoldersStarted(long accountId) {
}
public void listFoldersFailed(EmailContent.Account account, String message) {
public void listFoldersFailed(long accountId, String message) {
}
public void listFoldersFinished(EmailContent.Account account) {
public void listFoldersFinished(long accountId) {
}
public void synchronizeMailboxStarted(EmailContent.Account account, EmailContent.Mailbox folder)
public void synchronizeMailboxStarted(long accountId, long mailboxId)
{
}
public void synchronizeMailboxFinished(EmailContent.Account account,
EmailContent.Mailbox folder, int totalMessagesInMailbox, int numNewMessages) {
public void synchronizeMailboxFinished(long accountId,
long mailboxId, int totalMessagesInMailbox, int numNewMessages) {
}
public void synchronizeMailboxFailed(EmailContent.Account account, EmailContent.Mailbox folder,
public void synchronizeMailboxFailed(long accountId, long mailboxId,
Exception e) {
}
@ -62,7 +62,7 @@ public class MessagingListener {
public void checkMailStarted(Context context, long accountId, long tag) {
}
public void checkMailFinished(Context context, long accountId, long folderId, long tag) {
public void checkMailFinished(Context context, long accountId, long mailboxId, long tag) {
}
public void sendPendingMessagesStarted(long accountId, long messageId) {
@ -74,11 +74,7 @@ public class MessagingListener {
public void sendPendingMessagesFailed(long accountId, long messageId, Exception reason) {
}
public void emptyTrashCompleted(EmailContent.Account account) {
}
public void messageUidChanged(EmailContent.Account account, String folder,
String oldUid, String newUid) {
public void messageUidChanged(long accountId, long mailboxId, String oldUid, String newUid) {
}
public void loadAttachmentStarted(

View File

@ -1375,33 +1375,33 @@ public class FolderMessageList extends ExpandableListActivity {
private ArrayList<FolderInfoHolder> mFolders = new ArrayList<FolderInfoHolder>();
private MessagingListener mListener = new MessagingListener() {
@Override
public void listFoldersStarted(EmailContent.Account account) {
if (!account.equals(mAccount)) {
return;
}
mHandler.progress(true);
}
// @Override
// public void listFoldersStarted(EmailContent.Account account) {
// if (!account.equals(mAccount)) {
// return;
// }
// mHandler.progress(true);
// }
@Override
public void listFoldersFailed(EmailContent.Account account, String message) {
if (!account.equals(mAccount)) {
return;
}
mHandler.progress(false);
if (Email.LOGD) {
Log.v(Email.LOG_TAG, "listFoldersFailed " + message);
}
}
// @Override
// public void listFoldersFailed(EmailContent.Account account, String message) {
// if (!account.equals(mAccount)) {
// return;
// }
// mHandler.progress(false);
// if (Email.LOGD) {
// Log.v(Email.LOG_TAG, "listFoldersFailed " + message);
// }
// }
@Override
public void listFoldersFinished(EmailContent.Account account) {
if (!account.equals(mAccount)) {
return;
}
mHandler.progress(false);
mHandler.listFoldersFinished();
}
// @Override
// public void listFoldersFinished(EmailContent.Account account) {
// if (!account.equals(mAccount)) {
// return;
// }
// mHandler.progress(false);
// mHandler.listFoldersFinished();
// }
/*
@Override
@ -1441,71 +1441,71 @@ public class FolderMessageList extends ExpandableListActivity {
mHandler.synchronizeMessages(folder, messages);
}
*/
@Override
public void synchronizeMailboxStarted(EmailContent.Account account,
EmailContent.Mailbox folder) {
if (!account.equals(mAccount)) {
return;
}
mHandler.progress(true);
// mHandler.folderLoading(folder, true);
// mHandler.folderStatus(folder, null, false);
}
// @Override
// public void synchronizeMailboxStarted(EmailContent.Account account,
// EmailContent.Mailbox folder) {
// if (!account.equals(mAccount)) {
// return;
// }
// mHandler.progress(true);
//// mHandler.folderLoading(folder, true);
//// mHandler.folderStatus(folder, null, false);
// }
@Override
public void synchronizeMailboxFinished(EmailContent.Account account,
EmailContent.Mailbox folder, int totalMessagesInMailbox, int numNewMessages) {
if (!account.equals(mAccount)) {
return;
}
mHandler.progress(false);
// mHandler.folderLoading(folder, false);
// mHandler.folderStatus(folder, null, false);
onRefresh(false);
}
// @Override
// public void synchronizeMailboxFinished(EmailContent.Account account,
// EmailContent.Mailbox folder, int totalMessagesInMailbox, int numNewMessages) {
// if (!account.equals(mAccount)) {
// return;
// }
// mHandler.progress(false);
//// mHandler.folderLoading(folder, false);
//// mHandler.folderStatus(folder, null, false);
// onRefresh(false);
// }
@Override
public void synchronizeMailboxFailed(EmailContent.Account account,
EmailContent.Mailbox folder, Exception e) {
if (!account.equals(mAccount)) {
return;
}
mHandler.progress(false);
// mHandler.folderLoading(folder, false);
// Use exception details to select a decent string
// TODO combine with very similar code in AccountSettingsCheckSetup
int id = R.string.status_network_error;
if (e instanceof AuthenticationFailedException) {
id = R.string.account_setup_failed_dlg_auth_message;
} else if (e instanceof CertificateValidationException) {
id = R.string.account_setup_failed_dlg_certificate_message;
} else if (e instanceof MessagingException) {
MessagingException me = (MessagingException) e;
switch (me.getExceptionType()) {
case MessagingException.IOERROR:
id = R.string.account_setup_failed_ioerror;
break;
case MessagingException.TLS_REQUIRED:
id = R.string.account_setup_failed_tls_required;
break;
case MessagingException.AUTH_REQUIRED:
id = R.string.account_setup_failed_auth_required;
break;
case MessagingException.GENERAL_SECURITY:
id = R.string.account_setup_failed_security;
break;
}
}
// mHandler.folderStatus(folder, getString(id), true);
}
// @Override
// public void synchronizeMailboxFailed(EmailContent.Account account,
// EmailContent.Mailbox folder, Exception e) {
// if (!account.equals(mAccount)) {
// return;
// }
// mHandler.progress(false);
//// mHandler.folderLoading(folder, false);
// // Use exception details to select a decent string
// // TODO combine with very similar code in AccountSettingsCheckSetup
// int id = R.string.status_network_error;
// if (e instanceof AuthenticationFailedException) {
// id = R.string.account_setup_failed_dlg_auth_message;
// } else if (e instanceof CertificateValidationException) {
// id = R.string.account_setup_failed_dlg_certificate_message;
// } else if (e instanceof MessagingException) {
// MessagingException me = (MessagingException) e;
// switch (me.getExceptionType()) {
// case MessagingException.IOERROR:
// id = R.string.account_setup_failed_ioerror;
// break;
// case MessagingException.TLS_REQUIRED:
// id = R.string.account_setup_failed_tls_required;
// break;
// case MessagingException.AUTH_REQUIRED:
// id = R.string.account_setup_failed_auth_required;
// break;
// case MessagingException.GENERAL_SECURITY:
// id = R.string.account_setup_failed_security;
// break;
// }
// }
//// mHandler.folderStatus(folder, getString(id), true);
// }
@Override
public void emptyTrashCompleted(EmailContent.Account account) {
if (!account.equals(mAccount)) {
return;
}
onRefresh(false);
}
// @Override
// public void emptyTrashCompleted(EmailContent.Account account) {
// if (!account.equals(mAccount)) {
// return;
// }
// onRefresh(false);
// }
// @Override
// public void sendPendingMessagesCompleted(EmailContent.Account account) {
@ -1540,14 +1540,14 @@ public class FolderMessageList extends ExpandableListActivity {
// //mHandler.folderStatus(account.getOutboxFolderName(), reason.getMessage(), false);
// }
@Override
public void messageUidChanged(EmailContent.Account account, String folder,
String oldUid, String newUid) {
if (!mAccount.equals(account)) {
return;
}
mHandler.messageUidChanged(folder, oldUid, newUid);
}
// @Override
// public void messageUidChanged(EmailContent.Account account, String folder,
// String oldUid, String newUid) {
// if (!mAccount.equals(account)) {
// return;
// }
// mHandler.messageUidChanged(folder, oldUid, newUid);
// }
};
private Drawable mAttachmentIcon;

View File

@ -910,7 +910,7 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
protected Long doInBackground(Void... params) {
// See if we can find the requested mailbox in the DB.
long mailboxId = Mailbox.findMailboxOfType(MessageList.this, mAccountId, mMailboxType);
if (mailboxId == -1 && mOkToRecurse) {
if (mailboxId == Mailbox.NO_MAILBOX && mOkToRecurse) {
// Not found - launch network lookup
mControllerCallback.mWaitForMailboxType = mMailboxType;
mController.updateMailboxList(mAccountId, mControllerCallback);
@ -920,7 +920,7 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
@Override
protected void onPostExecute(Long mailboxId) {
if (mailboxId != -1) {
if (mailboxId != Mailbox.NO_MAILBOX) {
mMailboxId = mailboxId;
mSetTitleTask = new SetTitleTask(mMailboxId);
mSetTitleTask.execute();