From 05649dca2f59f28cd4295e041045a605badddb15 Mon Sep 17 00:00:00 2001 From: Tony Mantler Date: Wed, 30 Oct 2013 15:56:33 -0700 Subject: [PATCH] Coalesce notifications while in applyBatch Also divert all notifications through notifyUI() Change-Id: If3b1ee05a8933bed5718e7b90137dbb0139a761a --- .../android/email/provider/EmailProvider.java | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/com/android/email/provider/EmailProvider.java b/src/com/android/email/provider/EmailProvider.java index 972698f05..5eef21704 100644 --- a/src/com/android/email/provider/EmailProvider.java +++ b/src/com/android/email/provider/EmailProvider.java @@ -123,6 +123,7 @@ import com.android.mail.widget.BaseWidgetProvider; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import java.io.File; import java.io.FileDescriptor; @@ -665,7 +666,7 @@ public class EmailProvider extends ContentProvider { if (match == ACCOUNT_ID) { notifyUI(UIPROVIDER_ACCOUNT_NOTIFIER, id); - resolver.notifyChange(UIPROVIDER_ALL_ACCOUNTS_NOTIFIER, null); + notifyUI(UIPROVIDER_ALL_ACCOUNTS_NOTIFIER, null); } else if (match == MAILBOX_ID) { notifyUIFolder(id, accountId); } else if (match == ATTACHMENT_ID) { @@ -722,7 +723,7 @@ public class EmailProvider extends ContentProvider { sendNotifierChange(getBaseNotificationUri(match), NOTIFICATION_OP_DELETE, id); // Notify all email content cursors - resolver.notifyChange(EmailContent.CONTENT_URI, null); + notifyUI(EmailContent.CONTENT_URI, null); return result; } @@ -853,7 +854,7 @@ public class EmailProvider extends ContentProvider { if (!uri.getBooleanQueryParameter(IS_UIPROVIDER, false)) { notifyUIAccount(longId); } - resolver.notifyChange(UIPROVIDER_ALL_ACCOUNTS_NOTIFIER, null); + notifyUI(UIPROVIDER_ALL_ACCOUNTS_NOTIFIER, null); break; case UPDATED_MESSAGE: case DELETED_MESSAGE: @@ -909,7 +910,7 @@ public class EmailProvider extends ContentProvider { sendNotifierChange(getBaseNotificationUri(match), NOTIFICATION_OP_INSERT, id); // Notify all existing cursors. - resolver.notifyChange(EmailContent.CONTENT_URI, null); + notifyUI(EmailContent.CONTENT_URI, null); return resultUri; } @@ -1857,7 +1858,7 @@ public class EmailProvider extends ContentProvider { updateAccountSyncInterval(Long.parseLong(id), values); // Notify individual account and "all accounts" notifyUI(UIPROVIDER_ACCOUNT_NOTIFIER, id); - resolver.notifyChange(UIPROVIDER_ALL_ACCOUNTS_NOTIFIER, null); + notifyUI(UIPROVIDER_ALL_ACCOUNTS_NOTIFIER, null); restartPushForAccount(context, db, values, id); } break; @@ -1926,7 +1927,7 @@ public class EmailProvider extends ContentProvider { // Notify all notifier cursors sendNotifierChange(getBaseNotificationUri(match), NOTIFICATION_OP_UPDATE, id); - resolver.notifyChange(notificationUri, null); + notifyUI(notificationUri, null); return result; } @@ -1934,7 +1935,7 @@ public class EmailProvider extends ContentProvider { final long id = extras.getLong(EmailServiceStatus.SYNC_STATUS_ID); final int statusCode = extras.getInt(EmailServiceStatus.SYNC_STATUS_CODE); final Uri uri = ContentUris.withAppendedId(FOLDER_STATUS_URI, id); - EmailProvider.this.getContext().getContentResolver().notifyChange(uri, null); + notifyUI(uri, null); final boolean inProgress = statusCode == EmailServiceStatus.IN_PROGRESS; if (inProgress) { RefreshStatusMonitor.getInstance(getContext()).setSyncStarted(id); @@ -2084,9 +2085,9 @@ public class EmailProvider extends ContentProvider { longId = Long.valueOf(id); } catch (NumberFormatException ignore) {} if (longId > 0) { - resolver.notifyChange(ContentUris.withAppendedId(baseUri, longId), null); + notifyUI(baseUri, id); } else { - resolver.notifyChange(baseUri, null); + notifyUI(baseUri, null); } // We want to send the message list changed notification if baseUri is Message.NOTIFIER_URI. @@ -2104,9 +2105,17 @@ public class EmailProvider extends ContentProvider { context.sendBroadcast(intent); } + private Set mBatchNotifications; + @Override public ContentProviderResult[] applyBatch(ArrayList operations) throws OperationApplicationException { + /** + * Collect notification URIs to notify at the end of batch processing. + * These are populated by calls to notifyUI() by way of update(), insert() and delete() + * calls made in super.applyBatch() + */ + mBatchNotifications = Sets.newHashSet(); Context context = getContext(); SQLiteDatabase db = getDatabase(context); db.beginTransaction(); @@ -2116,6 +2125,11 @@ public class EmailProvider extends ContentProvider { return results; } finally { db.endTransaction(); + final Set notifications = mBatchNotifications; + mBatchNotifications = null; + for (final Uri uri : notifications) { + context.getContentResolver().notifyChange(uri, null); + } } } @@ -4613,7 +4627,7 @@ public class EmailProvider extends ContentProvider { if (sentMailbox == null) return null; final Uri messageUri = uiSaveMessage(msg, mailbox, extras); // Kick observers - context.getContentResolver().notifyChange(Mailbox.CONTENT_URI, null); + notifyUI(Mailbox.CONTENT_URI, null); return messageUri; } @@ -4636,11 +4650,11 @@ public class EmailProvider extends ContentProvider { * @param folders array of folder Uris to update * @return number of folders updated */ - private static int updateTimestamp(final Context context, String id, Uri[] folders){ + private int updateTimestamp(final Context context, String id, Uri[] folders){ int updated = 0; final long now = System.currentTimeMillis(); final ContentResolver resolver = context.getContentResolver(); - final ContentValues touchValues = new ContentValues(); + final ContentValues touchValues = new ContentValues(1); for (final Uri folder : folders) { touchValues.put(MailboxColumns.LAST_TOUCHED_TIME, now); LogUtils.d(TAG, "updateStamp: %s updated", folder); @@ -4649,7 +4663,7 @@ public class EmailProvider extends ContentProvider { final Uri toNotify = UIPROVIDER_RECENT_FOLDERS_NOTIFIER.buildUpon().appendPath(id).build(); LogUtils.d(TAG, "updateTimestamp: Notifying on %s", toNotify); - resolver.notifyChange(toNotify, null); + notifyUI(toNotify, null); return updated; } @@ -5192,9 +5206,13 @@ public class EmailProvider extends ContentProvider { notifyUIFolder(Long.toString(folderId), accountId); } - private void notifyUI(Uri uri, String id) { + private void notifyUI(final Uri uri, final String id) { final Uri notifyUri = (id != null) ? uri.buildUpon().appendPath(id).build() : uri; - getContext().getContentResolver().notifyChange(notifyUri, null); + if (mBatchNotifications != null) { + mBatchNotifications.add(notifyUri); + } else { + getContext().getContentResolver().notifyChange(notifyUri, null); + } } private void notifyUI(Uri uri, long id) {