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
diff --git a/src/com/android/exchange/SyncManager.java b/src/com/android/exchange/SyncManager.java
index dae467e..57284ce 100644
--- a/src/com/android/exchange/SyncManager.java
+++ b/src/com/android/exchange/SyncManager.java
@@ -1321,31 +1321,38 @@
}
}
- 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();
}
}
}