From 7cda118d3547695202b4ed051323671ba7afe2a7 Mon Sep 17 00:00:00 2001 From: satok Date: Wed, 10 Mar 2010 22:53:13 +0900 Subject: [PATCH] Extract delete acount function from UI thread to async task BUG: 2474078 BUG: 2438333 Change-Id: Id9aac4c73064f05aa666cda26005b61c04fc262e --- .../email/activity/AccountFolderList.java | 109 ++++++++++++------ .../email/activity/AccountFolderListItem.java | 4 + 2 files changed, 80 insertions(+), 33 deletions(-) diff --git a/src/com/android/email/activity/AccountFolderList.java b/src/com/android/email/activity/AccountFolderList.java index 1c0b7b447..e438e2bd1 100644 --- a/src/com/android/email/activity/AccountFolderList.java +++ b/src/com/android/email/activity/AccountFolderList.java @@ -28,6 +28,7 @@ import com.android.email.mail.MessagingException; import com.android.email.mail.Store; import com.android.email.provider.EmailContent; import com.android.email.provider.EmailContent.Account; +import com.android.email.provider.EmailContent.AccountColumns; import com.android.email.provider.EmailContent.Mailbox; import com.android.email.provider.EmailContent.MailboxColumns; import com.android.email.provider.EmailContent.Message; @@ -39,6 +40,7 @@ import android.app.Dialog; import android.app.ListActivity; import android.app.NotificationManager; import android.content.ContentUris; +import android.content.ContentValues; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -68,6 +70,8 @@ import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; +import java.util.ArrayList; + public class AccountFolderList extends ListActivity implements OnItemClickListener { private static final int DIALOG_REMOVE_ACCOUNT = 1; /** @@ -88,6 +92,7 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen private AccountsAdapter mListAdapter; private LoadAccountsTask mLoadAccountsTask; + private DeleteAccountTask mDeleteAccountTask; private MessageListHandler mHandler = new MessageListHandler(); private ControllerResults mControllerCallback = new ControllerResults(); @@ -206,6 +211,11 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen mLoadAccountsTask.cancel(true); mLoadAccountsTask = null; } + if (mDeleteAccountTask != null && + mDeleteAccountTask.getStatus() != DeleteAccountTask.Status.FINISHED) { + mDeleteAccountTask.cancel(false); // false == allow the cancel to run to completion + mDeleteAccountTask = null; + } } public void onItemClick(AdapterView parent, View view, int position, long id) { @@ -256,7 +266,7 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen /** * Build the group and child cursors that support the summary views (aka "at a glance"). * - * This is a placeholder implementation with significant problems that need to be addressed: + * This is a placeholder implementation with signifiあcant problems that need to be addressed: * * TODO: We should only show summary mailboxes if they are non-empty. So there needs to be * a more dynamic child-cursor here, probably listening for update notifications on a number @@ -322,7 +332,6 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen * Async task to handle the accounts query outside of the UI thread */ private class LoadAccountsTask extends AsyncTask { - @Override protected Object[] doInBackground(Void... params) { // Create the summaries cursor @@ -331,8 +340,7 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen // TODO use a custom projection and don't have to sample all of these columns Cursor c2 = AccountFolderList.this.managedQuery( EmailContent.Account.CONTENT_URI, - EmailContent.Account.CONTENT_PROJECTION, - null, null, null); + EmailContent.Account.CONTENT_PROJECTION, null, null, null); Long defaultAccount = Account.getDefaultAccountId(AccountFolderList.this); return new Object[] { c1, c2 , defaultAccount}; } @@ -348,6 +356,44 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen } } + private class DeleteAccountTask extends AsyncTask { + private long mAccountId; + private String mAccountUri; + + public DeleteAccountTask(long accountId, String accountUri) { + mAccountId = accountId; + mAccountUri = accountUri; + } + + @Override + protected Void doInBackground(Void... params) { + try { + // Delete Remote store at first. + Store.getInstance(mAccountUri, getApplication(), null).delete(); + // Remove the Store instance from cache. + Store.removeInstance(mAccountUri); + Uri uri = ContentUris.withAppendedId( + EmailContent.Account.CONTENT_URI, mAccountId); + AccountFolderList.this.getContentResolver().delete(uri, null, null); + // Update the backup (side copy) of the accounts + AccountBackupRestore.backupAccounts(AccountFolderList.this); + // Release or relax device administration, if relevant + SecurityPolicy.getInstance(AccountFolderList.this).reducePolicies(); + } catch (Exception e) { + // Ignore + } + Email.setServicesEnabled(AccountFolderList.this); + return null; + } + + @Override + protected void onPostExecute(Void v) { + if (!isCancelled()) { + updateAccounts(); + } + } + } + private void updateAccounts() { if (mLoadAccountsTask != null && mLoadAccountsTask.getStatus() != LoadAccountsTask.Status.FINISHED) { @@ -415,39 +461,20 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen .setPositiveButton(R.string.okay_action, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dismissDialog(DIALOG_REMOVE_ACCOUNT); - try { - // Clear notifications, which may become stale here - NotificationManager notificationManager = (NotificationManager) - getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancel(MailService.NOTIFICATION_ID_NEW_MESSAGES); - // Delete Remote store at first. - Store.getInstance( - mSelectedContextAccount.getStoreUri(AccountFolderList.this), - getApplication(), null).delete(); - // Remove the Store instance from cache. - Store.removeInstance(mSelectedContextAccount.getStoreUri( - AccountFolderList.this)); - Uri uri = ContentUris.withAppendedId( - EmailContent.Account.CONTENT_URI, mSelectedContextAccount.mId); - AccountFolderList.this.getContentResolver().delete(uri, null, null); - // Update the backup (side copy) of the accounts - AccountBackupRestore.backupAccounts(AccountFolderList.this); - // Release or relax device administration, if relevant - SecurityPolicy.getInstance(AccountFolderList.this).reducePolicies(); - } catch (Exception e) { - // Ignore - } - Email.setServicesEnabled(AccountFolderList.this); - - // Jump to account setup if the last/only account was deleted + // Clear notifications, which may become stale here + NotificationManager notificationManager = (NotificationManager) + getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.cancel(MailService.NOTIFICATION_ID_NEW_MESSAGES); int numAccounts = EmailContent.count(AccountFolderList.this, Account.CONTENT_URI, null, null); - if (numAccounts == 0) { + mListAdapter.addOnDeletingAccount(mSelectedContextAccount.mId); + mDeleteAccountTask = (DeleteAccountTask) new DeleteAccountTask( + mSelectedContextAccount.mId, + mSelectedContextAccount.getStoreUri(AccountFolderList.this)).execute(); + if (numAccounts == 1) { AccountSetupBasics.actionNewAccount(AccountFolderList.this); finish(); } - // Update unread counts and the default sender Id - updateAccounts(); } }) .setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener() { @@ -663,6 +690,7 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen private int mMailboxesCount; private int mSeparatorPosition; long mDefaultAccountId; + ArrayList mOnDeletingAccounts = new ArrayList(); public static AccountsAdapter getInstance(Cursor mailboxesCursor, Cursor accountsCursor, Context context, long defaultAccountId) { @@ -689,6 +717,14 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen return position >= mMailboxesCount; } + public void addOnDeletingAccount(long accountId) { + mOnDeletingAccounts.add(accountId); + } + + public boolean isOnDeletingAccountView(long accountId) { + return mOnDeletingAccounts.contains(accountId); + } + /** * This is used as a callback from the list items, for clicks in the folder "button" * @@ -879,7 +915,14 @@ public class AccountFolderList extends ListActivity implements OnItemClickListen */ @Override public boolean isEnabled(int position) { - return position != mSeparatorPosition; + if (position == mSeparatorPosition) { + return false; + } else if (isAccount(position)) { + Long id = ((MergeCursor)getItem(position)).getLong(Account.CONTENT_ID_COLUMN); + return !isOnDeletingAccountView(id); + } else { + return true; + } } /** diff --git a/src/com/android/email/activity/AccountFolderListItem.java b/src/com/android/email/activity/AccountFolderListItem.java index 6ad21dbd2..1703bc038 100644 --- a/src/com/android/email/activity/AccountFolderListItem.java +++ b/src/com/android/email/activity/AccountFolderListItem.java @@ -66,6 +66,10 @@ public class AccountFolderListItem extends LinearLayout { */ @Override public boolean onTouchEvent(MotionEvent event) { + if (mAdapter.isOnDeletingAccountView(mAccountId)) { + return true; + } + // Short-circuit all of this for list items w/o folder buttons if (!mHasFolderButton) { return super.onTouchEvent(event);