Fix remote wipe with mobile sync server DO NOT MERGE

* It appears as if our running multiple sync threads can confuse the
  mobile sync server during a remote wipe (the server expects the next
  client response to be an acknowledgment, whereas it might well be
  a command or response from a different thread)
* To avoid this, we first put the account on security hold and then
  shut down all other sync threads for the account
* After this, we send the acknowledgment and the remote wipe proceeds
  normally.
* NOTE: It's possible that, due to the vagaries of multithreaded
  operation, one of the other syncing threads could still send a non-
  acknowledgment response to the server before our provisioning thread
  gets a chance to send its acknowledgment.  However, since the other
  syncing threads will terminate (and not restart, because of the hold),
  the provision/remote wipe/ack sequence will work on the subsequent
  attempt

Bug: 2844888
Backport From: Ib4ffbbc67b681e69176b6c1d5515fa80c7d1e121
Backport From: Ie9e944bd39f331c2ddc0f0ba303a3d5684f6f033

Change-Id: Ie57f13a5ca2149961a48b99afaebb812f1cbc88e
This commit is contained in:
Andrew Stadler 2010-10-29 14:13:49 -07:00
parent 89a799c8d4
commit 9031e67b7e
3 changed files with 14 additions and 3 deletions

View File

@ -1282,17 +1282,28 @@ public class EasSyncService extends AbstractSyncService {
}
if (pp.getRemoteWipe()) {
// We've gotten a remote wipe command
SyncManager.alwaysLog("!!! Remote wipe request received");
// Start by setting the account to security hold
sp.setAccountHoldFlag(mAccount, true);
// Force a stop to any running syncs for this account (except this one)
SyncManager.stopNonAccountMailboxSyncsForAccount(mAccount.mId);
// If we're not the admin, we can't do the wipe, so just return
if (!sp.isActiveAdmin()) return false;
if (!sp.isActiveAdmin()) {
SyncManager.alwaysLog("!!! Not device admin; can't wipe");
return false;
}
// First, we've got to acknowledge it, but wrap the wipe in try/catch so that
// we wipe the device regardless of any errors in acknowledgment
try {
SyncManager.alwaysLog("!!! Acknowledging remote wipe to server");
acknowledgeRemoteWipe(pp.getPolicyKey());
} catch (Exception e) {
// Because remote wipe is such a high priority task, we don't want to
// circumvent it if there's an exception in acknowledgment
}
// Then, tell SecurityPolicy to wipe the device
SyncManager.alwaysLog("!!! Executing remote wipe");
sp.remoteWipe();
return false;
} else if (sp.isActive(ps)) {

View File

@ -1332,7 +1332,7 @@ public class SyncManager extends Service implements Runnable {
*
* @param acctId
*/
static public void folderListReloaded(long acctId) {
static public void stopNonAccountMailboxSyncsForAccount(long acctId) {
SyncManager syncManager = INSTANCE;
if (syncManager != null) {
syncManager.stopAccountSyncs(acctId, false);

View File

@ -114,7 +114,7 @@ public class FolderSyncParser extends AbstractSyncParser {
mContentResolver.delete(Mailbox.CONTENT_URI, ALL_BUT_ACCOUNT_MAILBOX,
new String[] {Long.toString(mAccountId)});
// Stop existing syncs and reconstruct _main
SyncManager.folderListReloaded(mAccountId);
SyncManager.stopNonAccountMailboxSyncsForAccount(mAccountId);
res = true;
resetFolders = true;
} else {