Handle UI delete in EAS where the message is moved to trash

* Check for the folder of updated messages, and delete those now in trash
* Created convenience method for finding a mailbox of a particular type in
  an account (helpful for finding, say, an Inbox or Trash for a given account
* Fix deleted/updated message table so that the _id column is defined to be
  unique (to prevent duplicate change records from being written)
This commit is contained in:
Marc Blank 2009-07-14 13:08:19 -07:00
parent 316bb44e1a
commit 6b158f715b
5 changed files with 100 additions and 16 deletions

View File

@ -1630,7 +1630,13 @@ public abstract class EmailContent {
MailboxColumns.FLAG_VISIBLE, MailboxColumns.FLAGS, MailboxColumns.VISIBLE_LIMIT
};
/**
private static final String WHERE_TYPE_AND_ACCOUNT_KEY =
MailboxColumns.TYPE + "=? and " + MailboxColumns.ACCOUNT_KEY + "=?";
private static final int ID_PROJECTION_ID = 0;
private static final String[] ID_PROJECTION = new String[] { ID };
/**
* no public constructor since this is a utility class
*/
public Mailbox() {
@ -1731,6 +1737,28 @@ public abstract class EmailContent {
values.put(MailboxColumns.VISIBLE_LIMIT, mVisibleLimit);
return values;
}
/**
* Convenience method to return the id of a given type of Mailbox for a given Account
* @param context the caller's context, used to get a ContentResolver
* @param accountId the id of the account to be queried
* @param type the mailbox type, as defined above
* @return the id of the mailbox, or -1 if not found
*/
public static long findMailboxOfType(Context context, long accountId, int type) {
long mailboxId = -1;
String[] bindArguments = new String[] {Long.toString(type), Long.toString(accountId)};
Cursor c = context.getContentResolver().query(Mailbox.CONTENT_URI,
ID_PROJECTION, WHERE_TYPE_AND_ACCOUNT_KEY, bindArguments, null);
try {
if (c.moveToFirst()) {
mailboxId = c.getLong(ID_PROJECTION_ID);
}
} finally {
c.close();
}
return mailboxId;
}
}
public interface HostAuthColumns {

View File

@ -264,7 +264,7 @@ public class EmailProvider extends ContentProvider {
// For the updated and deleted tables, the id is assigned, but we do want to keep track
// of the ORDER of updates using an autoincrement primary key. We use the DATA column
// at this point; it has no other function
String altCreateString = " (" + EmailContent.RECORD_ID + " integer, "
String altCreateString = " (" + EmailContent.RECORD_ID + " integer unique, "
+ SyncColumns.ACCOUNT_KEY + " integer, "
+ SyncColumns.SERVER_ID + " integer, "
+ SyncColumns.SERVER_VERSION + " integer, "

View File

@ -14,11 +14,11 @@
* limitations under the License.
*/
/**
* This is a local copy of com.android.email.EmailProvider
*
* Last copied from com.android.email.EmailProvider on 7/2/09
*/
/**
* This is a local copy of com.android.email.EmailProvider
*
* Last copied from com.android.email.EmailProvider on 7/15/09
*/
package com.android.exchange;
@ -1637,7 +1637,13 @@ public abstract class EmailContent {
MailboxColumns.FLAG_VISIBLE, MailboxColumns.FLAGS, MailboxColumns.VISIBLE_LIMIT
};
/**
private static final String WHERE_TYPE_AND_ACCOUNT_KEY =
MailboxColumns.TYPE + "=? and " + MailboxColumns.ACCOUNT_KEY + "=?";
private static final int ID_PROJECTION_ID = 0;
private static final String[] ID_PROJECTION = new String[] { ID };
/**
* no public constructor since this is a utility class
*/
public Mailbox() {
@ -1738,6 +1744,28 @@ public abstract class EmailContent {
values.put(MailboxColumns.VISIBLE_LIMIT, mVisibleLimit);
return values;
}
/**
* Convenience method to return the id of a given type of Mailbox for a given Account
* @param context the caller's context, used to get a ContentResolver
* @param accountId the id of the account to be queried
* @param type the mailbox type, as defined above
* @return the id of the mailbox, or -1 if not found
*/
public static long findMailboxOfType(Context context, long accountId, int type) {
long mailboxId = -1;
String[] bindArguments = new String[] {Long.toString(type), Long.toString(accountId)};
Cursor c = context.getContentResolver().query(Mailbox.CONTENT_URI,
ID_PROJECTION, WHERE_TYPE_AND_ACCOUNT_KEY, bindArguments, null);
try {
if (c.moveToFirst()) {
mailboxId = c.getLong(ID_PROJECTION_ID);
}
} finally {
c.close();
}
return mailboxId;
}
}
public interface HostAuthColumns {

View File

@ -49,7 +49,6 @@ import android.net.NetworkInfo;
import android.net.Uri;
import android.net.NetworkInfo.State;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.PowerManager;
import android.os.RemoteException;

View File

@ -28,6 +28,7 @@ import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.os.RemoteException;
@ -46,7 +47,13 @@ import com.android.exchange.EmailContent.SyncColumns;
*/
public class EasEmailSyncAdapter extends EasSyncAdapter {
private static final String[] UPDATES_PROJECTION = {MessageColumns.FLAG_READ};
private static final int UPDATES_READ_COLUMN = 0;
private static final int UPDATES_MAILBOX_KEY_COLUMN = 1;
private static final int UPDATES_SERVER_ID_COLUMN = 2;
private static final String[] UPDATES_PROJECTION =
{MessageColumns.FLAG_READ, MessageColumns.MAILBOX_KEY, SyncColumns.SERVER_ID};
String[] bindArguments = new String[2];
ArrayList<Long> mDeletedIdList = new ArrayList<Long>();
@ -69,8 +76,6 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
private String mMailboxIdAsString;
String[] bindArguments = new String[2];
public EasEmailSyncParser(InputStream in, EasSyncService service) throws IOException {
super(in, service);
mMailboxIdAsString = Long.toString(mMailbox.mId);
@ -337,6 +342,11 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
ops.add(ContentProviderOperation.newDelete(
ContentUris.withAppendedId(Message.DELETED_CONTENT_URI, id)).build());
}
// And same with the updates
for (Long id: mUpdatedIdList) {
ops.add(ContentProviderOperation.newDelete(
ContentUris.withAppendedId(Message.UPDATED_CONTENT_URI, id)).build());
}
try {
mService.mContext.getContentResolver()
@ -358,7 +368,8 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
@Override
public boolean sendLocalChanges(EasSerializer s, EasSyncService service) throws IOException {
ContentResolver cr = service.mContext.getContentResolver();
Context context = service.mContext;
ContentResolver cr = context.getContentResolver();
// Find any of our deleted items
Cursor c = cr.query(Message.DELETED_CONTENT_URI, Message.LIST_PROJECTION,
@ -383,11 +394,15 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
c.close();
}
// Find our trash mailbox, since deletions will have been moved there...
long trashMailboxId =
Mailbox.findMailboxOfType(context, mMailbox.mAccountKey, Mailbox.TYPE_TRASH);
// Do the same now for updated items
c = cr.query(Message.UPDATED_CONTENT_URI, Message.LIST_PROJECTION,
MessageColumns.MAILBOX_KEY + '=' + mMailbox.mId, null, null);
// We keep track of the list of updated item id's so that we can remove them from the
// deleted table after the server receives our command
// We keep track of the list of updated item id's as we did above with deleted items
mUpdatedIdList.clear();
try {
while (c.moveToNext()) {
@ -403,7 +418,21 @@ public class EasEmailSyncAdapter extends EasSyncAdapter {
if (!currentCursor.moveToFirst()) {
continue;
}
int read = currentCursor.getInt(0);
// If the message is now in the trash folder, it has been deleted by the user
if (currentCursor.getLong(UPDATES_MAILBOX_KEY_COLUMN) == trashMailboxId) {
if (first) {
s.start("Commands");
first = false;
}
// Send the command to delete this message
s.start("Delete")
.data("ServerId", currentCursor.getString(UPDATES_SERVER_ID_COLUMN))
.end("Delete");
continue;
}
int read = currentCursor.getInt(UPDATES_READ_COLUMN);
if (read == c.getInt(Message.LIST_READ_COLUMN)) {
// The read state hasn't really changed, so move on...
continue;