Move account delete logic to EmailProvider
* This functionality had to move away from Controller Change-Id: I557918a325eab8c83a9728fa1ce33dde8b86158f
This commit is contained in:
parent
ab6321e2c4
commit
ebb79619e8
|
@ -965,5 +965,4 @@ public final class Account extends EmailContent implements AccountColumns, Parce
|
||||||
sb.append(']');
|
sb.append(']');
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -637,4 +637,8 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns
|
||||||
return new Mailbox[size];
|
return new Mailbox[size];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "[Mailbox " + mId + ": " + mDisplayName + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.email.mail.store.Pop3Store.Pop3Message;
|
import com.android.email.mail.store.Pop3Store.Pop3Message;
|
||||||
import com.android.email.provider.AccountBackupRestore;
|
|
||||||
import com.android.email.provider.Utilities;
|
import com.android.email.provider.Utilities;
|
||||||
import com.android.email.service.EmailServiceUtils;
|
import com.android.email.service.EmailServiceUtils;
|
||||||
import com.android.emailcommon.Logging;
|
import com.android.emailcommon.Logging;
|
||||||
|
@ -92,12 +91,6 @@ public class Controller {
|
||||||
};
|
};
|
||||||
private static final int MESSAGEID_TO_ACCOUNTID_COLUMN_ACCOUNTID = 1;
|
private static final int MESSAGEID_TO_ACCOUNTID_COLUMN_ACCOUNTID = 1;
|
||||||
|
|
||||||
private static final String MAILBOXES_FOR_ACCOUNT_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?";
|
|
||||||
private static final String MAILBOXES_FOR_ACCOUNT_EXCEPT_ACCOUNT_MAILBOX_SELECTION =
|
|
||||||
MAILBOXES_FOR_ACCOUNT_SELECTION + " AND " + MailboxColumns.TYPE + "!=" +
|
|
||||||
Mailbox.TYPE_EAS_ACCOUNT_MAILBOX;
|
|
||||||
private static final String MESSAGES_FOR_ACCOUNT_SELECTION = MessageColumns.ACCOUNT_KEY + "=?";
|
|
||||||
|
|
||||||
// Service callbacks as set up via setCallback
|
// Service callbacks as set up via setCallback
|
||||||
private static RemoteCallbackList<IEmailServiceCallback> sCallbackList =
|
private static RemoteCallbackList<IEmailServiceCallback> sCallbackList =
|
||||||
new RemoteCallbackList<IEmailServiceCallback>();
|
new RemoteCallbackList<IEmailServiceCallback>();
|
||||||
|
@ -971,99 +964,6 @@ public class Controller {
|
||||||
return getServiceForAccount(message.mAccountKey);
|
return getServiceForAccount(message.mAccountKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete an account.
|
|
||||||
*/
|
|
||||||
public void deleteAccount(final long accountId) {
|
|
||||||
EmailAsyncTask.runAsyncParallel(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
deleteAccountSync(accountId, mProviderContext);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete an account synchronously.
|
|
||||||
*/
|
|
||||||
public void deleteAccountSync(long accountId, Context context) {
|
|
||||||
try {
|
|
||||||
mLegacyControllerMap.remove(accountId);
|
|
||||||
// Get the account URI.
|
|
||||||
final Account account = Account.restoreAccountWithId(context, accountId);
|
|
||||||
if (account == null) {
|
|
||||||
return; // Already deleted?
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete account data, attachments, PIM data, etc.
|
|
||||||
deleteSyncedDataSync(accountId);
|
|
||||||
|
|
||||||
// Now delete the account itself
|
|
||||||
Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, accountId);
|
|
||||||
context.getContentResolver().delete(uri, null, null);
|
|
||||||
|
|
||||||
// For unit tests, don't run backup, security, and ui pieces.
|
|
||||||
if (mInUnitTests) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
AccountBackupRestore.backup(context);
|
|
||||||
SecurityPolicy.getInstance(context).reducePolicies();
|
|
||||||
Email.setServicesEnabledSync(context);
|
|
||||||
Email.setNotifyUiAccountsChanged(true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.w(Logging.LOG_TAG, "Exception while deleting account", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete all synced data, but don't delete the actual account. This is used when security
|
|
||||||
* policy requirements are not met, and we don't want to reveal any synced data, but we do
|
|
||||||
* wish to keep the account configured (e.g. to accept remote wipe commands).
|
|
||||||
*
|
|
||||||
* The only mailbox not deleted is the account mailbox (if any)
|
|
||||||
* Also, clear the sync keys on the remaining account, since the data is gone.
|
|
||||||
*
|
|
||||||
* SYNCHRONOUS - do not call from UI thread.
|
|
||||||
*
|
|
||||||
* @param accountId The account to wipe.
|
|
||||||
*/
|
|
||||||
public void deleteSyncedDataSync(long accountId) {
|
|
||||||
try {
|
|
||||||
// Delete synced attachments
|
|
||||||
AttachmentUtilities.deleteAllAccountAttachmentFiles(mProviderContext,
|
|
||||||
accountId);
|
|
||||||
|
|
||||||
// Delete synced email, leaving only an empty inbox. We do this in two phases:
|
|
||||||
// 1. Delete all non-inbox mailboxes (which will delete all of their messages)
|
|
||||||
// 2. Delete all remaining messages (which will be the inbox messages)
|
|
||||||
ContentResolver resolver = mProviderContext.getContentResolver();
|
|
||||||
String[] accountIdArgs = new String[] { Long.toString(accountId) };
|
|
||||||
resolver.delete(Mailbox.CONTENT_URI,
|
|
||||||
MAILBOXES_FOR_ACCOUNT_EXCEPT_ACCOUNT_MAILBOX_SELECTION,
|
|
||||||
accountIdArgs);
|
|
||||||
resolver.delete(Message.CONTENT_URI, MESSAGES_FOR_ACCOUNT_SELECTION, accountIdArgs);
|
|
||||||
|
|
||||||
// Delete sync keys on remaining items
|
|
||||||
ContentValues cv = new ContentValues();
|
|
||||||
cv.putNull(Account.SYNC_KEY);
|
|
||||||
resolver.update(Account.CONTENT_URI, cv, Account.ID_SELECTION, accountIdArgs);
|
|
||||||
cv.clear();
|
|
||||||
cv.putNull(Mailbox.SYNC_KEY);
|
|
||||||
resolver.update(Mailbox.CONTENT_URI, cv,
|
|
||||||
MAILBOXES_FOR_ACCOUNT_SELECTION, accountIdArgs);
|
|
||||||
|
|
||||||
// Delete PIM data (contacts, calendar), stop syncs, etc. if applicable
|
|
||||||
IEmailService service = getServiceForAccount(accountId);
|
|
||||||
if (service != null) {
|
|
||||||
service.deleteAccountPIMData(accountId);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.w(Logging.LOG_TAG, "Exception while deleting account synced data", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple callback for synchronous commands. For many commands, this can be largely ignored
|
* Simple callback for synchronous commands. For many commands, this can be largely ignored
|
||||||
* and the result is observed via provider cursors. The callback will *not* necessarily be
|
* and the result is observed via provider cursors. The callback will *not* necessarily be
|
||||||
|
|
|
@ -28,9 +28,11 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.OperationApplicationException;
|
import android.content.OperationApplicationException;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.email.provider.EmailProvider;
|
||||||
import com.android.email.service.EmailBroadcastProcessorService;
|
import com.android.email.service.EmailBroadcastProcessorService;
|
||||||
import com.android.emailcommon.Logging;
|
import com.android.emailcommon.Logging;
|
||||||
import com.android.emailcommon.provider.Account;
|
import com.android.emailcommon.provider.Account;
|
||||||
|
@ -582,7 +584,8 @@ public class SecurityPolicy {
|
||||||
NotificationController.getInstance(mContext).showSecurityUnsupportedNotification(
|
NotificationController.getInstance(mContext).showSecurityUnsupportedNotification(
|
||||||
account);
|
account);
|
||||||
// Erase data
|
// Erase data
|
||||||
Controller.getInstance(mContext).deleteSyncedDataSync(accountId);
|
Uri uri = EmailProvider.uiUri("uiaccountdata", accountId);
|
||||||
|
mContext.getContentResolver().delete(uri, null, null);
|
||||||
} else if (isActive(policy)) {
|
} else if (isActive(policy)) {
|
||||||
if (policyChanged) {
|
if (policyChanged) {
|
||||||
Log.d(Logging.LOG_TAG, "Notify policies for " + account.mDisplayName + " changed.");
|
Log.d(Logging.LOG_TAG, "Notify policies for " + account.mDisplayName + " changed.");
|
||||||
|
@ -661,8 +664,9 @@ public class SecurityPolicy {
|
||||||
Log.w(TAG, "Email administration disabled; deleting " + c.getCount() +
|
Log.w(TAG, "Email administration disabled; deleting " + c.getCount() +
|
||||||
" secured account(s)");
|
" secured account(s)");
|
||||||
while (c.moveToNext()) {
|
while (c.moveToNext()) {
|
||||||
Controller.getInstance(context).deleteAccountSync(
|
long accountId = c.getLong(EmailContent.ID_PROJECTION_COLUMN);
|
||||||
c.getLong(EmailContent.ID_PROJECTION_COLUMN), context);
|
Uri uri = EmailProvider.uiUri("uiaccountdata", accountId);
|
||||||
|
cr.delete(uri, null, null);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
c.close();
|
c.close();
|
||||||
|
@ -754,7 +758,8 @@ public class SecurityPolicy {
|
||||||
// Mark the account as "on hold".
|
// Mark the account as "on hold".
|
||||||
setAccountHoldFlag(context, account, true);
|
setAccountHoldFlag(context, account, true);
|
||||||
// Erase data
|
// Erase data
|
||||||
controller.deleteSyncedDataSync(accountId);
|
Uri uri = EmailProvider.uiUri("uiaccountdata", accountId);
|
||||||
|
context.getContentResolver().delete(uri, null, null);
|
||||||
// Report one or more were found
|
// Report one or more were found
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,11 +37,11 @@ import android.view.KeyEvent;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import com.android.email.Controller;
|
|
||||||
import com.android.email.R;
|
import com.android.email.R;
|
||||||
import com.android.email.activity.ActivityHelper;
|
import com.android.email.activity.ActivityHelper;
|
||||||
import com.android.email.mail.Sender;
|
import com.android.email.mail.Sender;
|
||||||
import com.android.email.mail.Store;
|
import com.android.email.mail.Store;
|
||||||
|
import com.android.email.provider.EmailProvider;
|
||||||
import com.android.emailcommon.Logging;
|
import com.android.emailcommon.Logging;
|
||||||
import com.android.emailcommon.provider.Account;
|
import com.android.emailcommon.provider.Account;
|
||||||
import com.android.emailcommon.provider.EmailContent.AccountColumns;
|
import com.android.emailcommon.provider.EmailContent.AccountColumns;
|
||||||
|
@ -678,11 +678,16 @@ public class AccountSettings extends PreferenceActivity {
|
||||||
/**
|
/**
|
||||||
* Delete the selected account
|
* Delete the selected account
|
||||||
*/
|
*/
|
||||||
public void deleteAccount(Account account) {
|
public void deleteAccount(final Account account) {
|
||||||
// Kick off the work to actually delete the account
|
// Kick off the work to actually delete the account
|
||||||
// Delete the account (note, this is async. Would be nice to get a callback.
|
new Thread(new Runnable() {
|
||||||
Controller.getInstance(this).deleteAccount(account.mId);
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Uri uri = EmailProvider.uiUri("uiaccount", account.mId);
|
||||||
|
getContentResolver().delete(uri, null, null);
|
||||||
|
}}).start();
|
||||||
|
|
||||||
|
// TODO: Remove ui glue for unified
|
||||||
// Then update the UI as appropriate:
|
// Then update the UI as appropriate:
|
||||||
// If single pane, return to the header list. If multi, rebuild header list
|
// If single pane, return to the header list. If multi, rebuild header list
|
||||||
if (onIsMultiPane()) {
|
if (onIsMultiPane()) {
|
||||||
|
|
|
@ -21,9 +21,9 @@ import android.accounts.AccountManagerFuture;
|
||||||
import android.accounts.AuthenticatorException;
|
import android.accounts.AuthenticatorException;
|
||||||
import android.accounts.OperationCanceledException;
|
import android.accounts.OperationCanceledException;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.email.Controller;
|
|
||||||
import com.android.emailcommon.Logging;
|
import com.android.emailcommon.Logging;
|
||||||
import com.android.emailcommon.provider.Account;
|
import com.android.emailcommon.provider.Account;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
@ -119,8 +119,8 @@ public class AccountReconciler {
|
||||||
Log.d(Logging.LOG_TAG,
|
Log.d(Logging.LOG_TAG,
|
||||||
"Account deleted in AccountManager; deleting from provider: " +
|
"Account deleted in AccountManager; deleting from provider: " +
|
||||||
providerAccountName);
|
providerAccountName);
|
||||||
Controller.getInstance(context).deleteAccountSync(providerAccount.mId,
|
Uri uri = EmailProvider.uiUri("uiaccount", providerAccount.mId);
|
||||||
providerContext);
|
context.getContentResolver().delete(uri, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import com.android.common.content.ProjectionMap;
|
||||||
import com.android.email.Email;
|
import com.android.email.Email;
|
||||||
import com.android.email.Preferences;
|
import com.android.email.Preferences;
|
||||||
import com.android.email.R;
|
import com.android.email.R;
|
||||||
|
import com.android.email.SecurityPolicy;
|
||||||
import com.android.email.provider.ContentCache.CacheToken;
|
import com.android.email.provider.ContentCache.CacheToken;
|
||||||
import com.android.email.service.AttachmentDownloadService;
|
import com.android.email.service.AttachmentDownloadService;
|
||||||
import com.android.email.service.EmailServiceUtils;
|
import com.android.email.service.EmailServiceUtils;
|
||||||
|
@ -62,6 +63,7 @@ import com.android.emailcommon.provider.Mailbox;
|
||||||
import com.android.emailcommon.provider.Policy;
|
import com.android.emailcommon.provider.Policy;
|
||||||
import com.android.emailcommon.provider.QuickResponse;
|
import com.android.emailcommon.provider.QuickResponse;
|
||||||
import com.android.emailcommon.service.EmailServiceProxy;
|
import com.android.emailcommon.service.EmailServiceProxy;
|
||||||
|
import com.android.emailcommon.service.IEmailService;
|
||||||
import com.android.emailcommon.service.IEmailServiceCallback;
|
import com.android.emailcommon.service.IEmailServiceCallback;
|
||||||
import com.android.emailcommon.service.SearchParams;
|
import com.android.emailcommon.service.SearchParams;
|
||||||
import com.android.emailcommon.utility.AttachmentUtilities;
|
import com.android.emailcommon.utility.AttachmentUtilities;
|
||||||
|
@ -212,6 +214,7 @@ public class EmailProvider extends ContentProvider {
|
||||||
private static final int UI_ATTACHMENTS = UI_BASE + 14;
|
private static final int UI_ATTACHMENTS = UI_BASE + 14;
|
||||||
private static final int UI_ATTACHMENT = UI_BASE + 15;
|
private static final int UI_ATTACHMENT = UI_BASE + 15;
|
||||||
private static final int UI_SEARCH = UI_BASE + 16;
|
private static final int UI_SEARCH = UI_BASE + 16;
|
||||||
|
private static final int UI_ACCOUNT_DATA = UI_BASE + 17;
|
||||||
|
|
||||||
// MUST ALWAYS EQUAL THE LAST OF THE PREVIOUS BASE CONSTANTS
|
// MUST ALWAYS EQUAL THE LAST OF THE PREVIOUS BASE CONSTANTS
|
||||||
private static final int LAST_EMAIL_PROVIDER_DB_BASE = UI_BASE;
|
private static final int LAST_EMAIL_PROVIDER_DB_BASE = UI_BASE;
|
||||||
|
@ -426,6 +429,7 @@ public class EmailProvider extends ContentProvider {
|
||||||
matcher.addURI(EmailContent.AUTHORITY, "uiattachments/#", UI_ATTACHMENTS);
|
matcher.addURI(EmailContent.AUTHORITY, "uiattachments/#", UI_ATTACHMENTS);
|
||||||
matcher.addURI(EmailContent.AUTHORITY, "uiattachment/#", UI_ATTACHMENT);
|
matcher.addURI(EmailContent.AUTHORITY, "uiattachment/#", UI_ATTACHMENT);
|
||||||
matcher.addURI(EmailContent.AUTHORITY, "uisearch/#", UI_SEARCH);
|
matcher.addURI(EmailContent.AUTHORITY, "uisearch/#", UI_SEARCH);
|
||||||
|
matcher.addURI(EmailContent.AUTHORITY, "uiaccountdata/#", UI_ACCOUNT_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -446,6 +450,14 @@ public class EmailProvider extends ContentProvider {
|
||||||
private SQLiteDatabase mDatabase;
|
private SQLiteDatabase mDatabase;
|
||||||
private SQLiteDatabase mBodyDatabase;
|
private SQLiteDatabase mBodyDatabase;
|
||||||
|
|
||||||
|
public static Uri uiUri(String type, long id) {
|
||||||
|
return Uri.parse(uiUriString(type, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String uiUriString(String type, long id) {
|
||||||
|
return "content://" + EmailContent.AUTHORITY + "/" + type + ((id == -1) ? "" : ("/" + id));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Orphan record deletion utility. Generates a sqlite statement like:
|
* Orphan record deletion utility. Generates a sqlite statement like:
|
||||||
* delete from <table> where <column> not in (select <foreignColumn> from <foreignTable>)
|
* delete from <table> where <column> not in (select <foreignColumn> from <foreignTable>)
|
||||||
|
@ -723,6 +735,10 @@ public class EmailProvider extends ContentProvider {
|
||||||
switch (match) {
|
switch (match) {
|
||||||
case UI_MESSAGE:
|
case UI_MESSAGE:
|
||||||
return uiDeleteMessage(uri);
|
return uiDeleteMessage(uri);
|
||||||
|
case UI_ACCOUNT_DATA:
|
||||||
|
return uiDeleteAccountData(uri);
|
||||||
|
case UI_ACCOUNT:
|
||||||
|
return uiDeleteAccount(uri);
|
||||||
// These are cases in which one or more Messages might get deleted, either by
|
// These are cases in which one or more Messages might get deleted, either by
|
||||||
// cascade or explicitly
|
// cascade or explicitly
|
||||||
case MAILBOX_ID:
|
case MAILBOX_ID:
|
||||||
|
@ -2241,7 +2257,7 @@ outer:
|
||||||
long mailboxId = Mailbox.findMailboxOfType(getContext(), accountId, Mailbox.TYPE_INBOX);
|
long mailboxId = Mailbox.findMailboxOfType(getContext(), accountId, Mailbox.TYPE_INBOX);
|
||||||
if (mailboxId != Mailbox.NO_MAILBOX) {
|
if (mailboxId != Mailbox.NO_MAILBOX) {
|
||||||
values.put(UIProvider.SettingsColumns.DEFAULT_INBOX,
|
values.put(UIProvider.SettingsColumns.DEFAULT_INBOX,
|
||||||
"content://" + EmailContent.AUTHORITY + "/uifolder/" + mailboxId);
|
uiUriString("uifolder", mailboxId));
|
||||||
}
|
}
|
||||||
StringBuilder sb = genSelect(sAccountSettingsMap, uiProjection, values);
|
StringBuilder sb = genSelect(sAccountSettingsMap, uiProjection, values);
|
||||||
sb.append(" FROM " + Account.TABLE_NAME + " WHERE " + AccountColumns.ID + "=?");
|
sb.append(" FROM " + Account.TABLE_NAME + " WHERE " + AccountColumns.ID + "=?");
|
||||||
|
@ -2520,7 +2536,7 @@ outer:
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Uri.parse("content://" + EmailContent.AUTHORITY + "/uimessage/" + msg.mId);
|
return uiUri("uimessage", msg.mId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2913,4 +2929,86 @@ outer:
|
||||||
return uiQuery(UI_FOLDER, ContentUris.withAppendedId(Mailbox.CONTENT_URI,
|
return uiQuery(UI_FOLDER, ContentUris.withAppendedId(Mailbox.CONTENT_URI,
|
||||||
searchMailbox.mId), projection);
|
searchMailbox.mId), projection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String MAILBOXES_FOR_ACCOUNT_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?";
|
||||||
|
private static final String MAILBOXES_FOR_ACCOUNT_EXCEPT_ACCOUNT_MAILBOX_SELECTION =
|
||||||
|
MAILBOXES_FOR_ACCOUNT_SELECTION + " AND " + MailboxColumns.TYPE + "!=" +
|
||||||
|
Mailbox.TYPE_EAS_ACCOUNT_MAILBOX;
|
||||||
|
private static final String MESSAGES_FOR_ACCOUNT_SELECTION = MessageColumns.ACCOUNT_KEY + "=?";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an account and clean it up
|
||||||
|
*/
|
||||||
|
private int uiDeleteAccount(Uri uri) {
|
||||||
|
Context context = getContext();
|
||||||
|
long accountId = Long.parseLong(uri.getLastPathSegment());
|
||||||
|
try {
|
||||||
|
// Get the account URI.
|
||||||
|
final Account account = Account.restoreAccountWithId(context, accountId);
|
||||||
|
if (account == null) {
|
||||||
|
return 0; // Already deleted?
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteAccountData(context, accountId);
|
||||||
|
|
||||||
|
// Now delete the account itself
|
||||||
|
uri = ContentUris.withAppendedId(Account.CONTENT_URI, accountId);
|
||||||
|
context.getContentResolver().delete(uri, null, null);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
AccountBackupRestore.backup(context);
|
||||||
|
SecurityPolicy.getInstance(context).reducePolicies();
|
||||||
|
Email.setServicesEnabledSync(context);
|
||||||
|
return 1;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(Logging.LOG_TAG, "Exception while deleting account", e);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int uiDeleteAccountData(Uri uri) {
|
||||||
|
Context context = getContext();
|
||||||
|
long accountId = Long.parseLong(uri.getLastPathSegment());
|
||||||
|
// Get the account URI.
|
||||||
|
final Account account = Account.restoreAccountWithId(context, accountId);
|
||||||
|
if (account == null) {
|
||||||
|
return 0; // Already deleted?
|
||||||
|
}
|
||||||
|
deleteAccountData(context, accountId);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteAccountData(Context context, long accountId) {
|
||||||
|
// Delete synced attachments
|
||||||
|
AttachmentUtilities.deleteAllAccountAttachmentFiles(context, accountId);
|
||||||
|
|
||||||
|
// Delete synced email, leaving only an empty inbox. We do this in two phases:
|
||||||
|
// 1. Delete all non-inbox mailboxes (which will delete all of their messages)
|
||||||
|
// 2. Delete all remaining messages (which will be the inbox messages)
|
||||||
|
ContentResolver resolver = context.getContentResolver();
|
||||||
|
String[] accountIdArgs = new String[] { Long.toString(accountId) };
|
||||||
|
resolver.delete(Mailbox.CONTENT_URI,
|
||||||
|
MAILBOXES_FOR_ACCOUNT_EXCEPT_ACCOUNT_MAILBOX_SELECTION,
|
||||||
|
accountIdArgs);
|
||||||
|
resolver.delete(Message.CONTENT_URI, MESSAGES_FOR_ACCOUNT_SELECTION, accountIdArgs);
|
||||||
|
|
||||||
|
// Delete sync keys on remaining items
|
||||||
|
ContentValues cv = new ContentValues();
|
||||||
|
cv.putNull(Account.SYNC_KEY);
|
||||||
|
resolver.update(Account.CONTENT_URI, cv, Account.ID_SELECTION, accountIdArgs);
|
||||||
|
cv.clear();
|
||||||
|
cv.putNull(Mailbox.SYNC_KEY);
|
||||||
|
resolver.update(Mailbox.CONTENT_URI, cv,
|
||||||
|
MAILBOXES_FOR_ACCOUNT_SELECTION, accountIdArgs);
|
||||||
|
|
||||||
|
// Delete PIM data (contacts, calendar), stop syncs, etc. if applicable
|
||||||
|
IEmailService service = EmailServiceUtils.getServiceForAccount(context, null, accountId);
|
||||||
|
if (service != null) {
|
||||||
|
try {
|
||||||
|
service.deleteAccountPIMData(accountId);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// Can't do anything about this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -424,7 +424,8 @@ public class ControllerProviderOpsTests extends ProviderTestCase2<EmailProvider>
|
||||||
long message4Id = message.mId;
|
long message4Id = message.mId;
|
||||||
|
|
||||||
// Now wipe account 1's data
|
// Now wipe account 1's data
|
||||||
mTestController.deleteSyncedDataSync(account1Id);
|
Uri uri = EmailProvider.uiUri("uiaccount", account1Id);
|
||||||
|
mProviderContext.getContentResolver().delete(uri, null, null);
|
||||||
|
|
||||||
// Confirm: Mailboxes gone (except account box), all messages gone, account survives
|
// Confirm: Mailboxes gone (except account box), all messages gone, account survives
|
||||||
assertNull(Mailbox.restoreMailboxWithId(mProviderContext, box1Id));
|
assertNull(Mailbox.restoreMailboxWithId(mProviderContext, box1Id));
|
||||||
|
|
Loading…
Reference in New Issue