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
diff --git a/src/com/android/exchange/EasSyncService.java b/src/com/android/exchange/EasSyncService.java
index 304f65f..20e1ea8 100644
--- a/src/com/android/exchange/EasSyncService.java
+++ b/src/com/android/exchange/EasSyncService.java
@@ -1282,17 +1282,28 @@
}
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)) {
diff --git a/src/com/android/exchange/SyncManager.java b/src/com/android/exchange/SyncManager.java
index ef0d5db..4feb79c 100644
--- a/src/com/android/exchange/SyncManager.java
+++ b/src/com/android/exchange/SyncManager.java
@@ -1332,7 +1332,7 @@
*
* @param acctId
*/
- static public void folderListReloaded(long acctId) {
+ static public void stopNonAccountMailboxSyncsForAccount(long acctId) {
SyncManager syncManager = INSTANCE;
if (syncManager != null) {
syncManager.stopAccountSyncs(acctId, false);
diff --git a/src/com/android/exchange/adapter/FolderSyncParser.java b/src/com/android/exchange/adapter/FolderSyncParser.java
index ed97d31..3706b18 100644
--- a/src/com/android/exchange/adapter/FolderSyncParser.java
+++ b/src/com/android/exchange/adapter/FolderSyncParser.java
@@ -114,7 +114,7 @@
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 {