From bb2f25a23a51db0cd7a564950dd9a0649bf01346 Mon Sep 17 00:00:00 2001 From: Marc Blank Date: Fri, 19 Mar 2010 09:06:50 -0700 Subject: [PATCH] Do alert work in background thread * An ANR was reported in MailboxAlarmReceiver * The reciever calls into SyncManager, which does some database operations, and may abort an I/O operation in a sync service thread * Move this potentially long-running code into a background thread Bug: 2215045 Change-Id: Id65c51f706b212d6b50af3921f3ba3dc2d014ce0 --- src/com/android/exchange/SyncManager.java | 43 +++++++++++++---------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/com/android/exchange/SyncManager.java b/src/com/android/exchange/SyncManager.java index dae467e1a..57284ce6f 100644 --- a/src/com/android/exchange/SyncManager.java +++ b/src/com/android/exchange/SyncManager.java @@ -1321,31 +1321,38 @@ public class SyncManager extends Service implements Runnable { } } - static public void alert(Context context, long id) { - SyncManager syncManager = INSTANCE; + static public void alert(Context context, final long id) { + final SyncManager syncManager = INSTANCE; checkSyncManagerServiceRunning(); if (id < 0) { kick("ping SyncManager"); } else if (syncManager == null) { context.startService(new Intent(context, SyncManager.class)); } else { - AbstractSyncService service = syncManager.mServiceMap.get(id); + final AbstractSyncService service = syncManager.mServiceMap.get(id); if (service != null) { - Mailbox m = Mailbox.restoreMailboxWithId(syncManager, id); - if (m != null) { - // We ignore drafts completely (doesn't sync). Changes in Outbox are handled - // in the checkMailboxes loop, so we can ignore these pings. - if (m.mType == Mailbox.TYPE_DRAFTS || m.mType == Mailbox.TYPE_OUTBOX) { - String[] args = new String[] {Long.toString(m.mId)}; - ContentResolver resolver = INSTANCE.mResolver; - resolver.delete(Message.DELETED_CONTENT_URI, WHERE_MAILBOX_KEY, args); - resolver.delete(Message.UPDATED_CONTENT_URI, WHERE_MAILBOX_KEY, args); - return; - } - service.mAccount = Account.restoreAccountWithId(INSTANCE, m.mAccountKey); - service.mMailbox = m; - service.alarm(); - } + // Handle alerts in a background thread, as we are typically called from a + // broadcast receiver, and are therefore running in the UI thread + new Thread(new Runnable() { + public void run() { + Mailbox m = Mailbox.restoreMailboxWithId(syncManager, id); + if (m != null) { + // We ignore drafts completely (doesn't sync). Changes in Outbox are + // handled in the checkMailboxes loop, so we can ignore these pings. + if (m.mType == Mailbox.TYPE_DRAFTS || m.mType == Mailbox.TYPE_OUTBOX) { + String[] args = new String[] {Long.toString(m.mId)}; + ContentResolver resolver = INSTANCE.mResolver; + resolver.delete(Message.DELETED_CONTENT_URI, WHERE_MAILBOX_KEY, + args); + resolver.delete(Message.UPDATED_CONTENT_URI, WHERE_MAILBOX_KEY, + args); + return; + } + service.mAccount = Account.restoreAccountWithId(INSTANCE, m.mAccountKey); + service.mMailbox = m; + service.alarm(); + } + }}).start(); } } }