From 2c548e0e11436b2dca2e45d9a80ac545d647a3ca Mon Sep 17 00:00:00 2001 From: Rubin Xu Date: Fri, 1 Apr 2016 17:47:28 +0100 Subject: [PATCH] Only cancel syncs for non-existent accounts updateRunningAccountsH() should check syncs against all accounts on the device, not only running accounts. Also add code to restore wrongly-canceled periodic syncs, saving users from a bad state where the only alternative is to remove and readd affected accounts. Bug: 27733283 Change-Id: I96bce87571c3b7c6cd1934cc967f11257f891f55 --- .../com/android/server/content/SyncManager.java | 16 +++++++++++- .../android/server/content/SyncStorageEngine.java | 29 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index e5342ceec1dc..db41a54f1a0a 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -1402,12 +1402,24 @@ public class SyncManager { } } + private void restoreLostPeriodicSyncsIfNeeded(int userId) { + List periodicSyncs = new ArrayList(); + for (SyncOperation sync : getAllPendingSyncs()) { + if (sync.isPeriodic && sync.target.userId == userId) { + periodicSyncs.add(sync); + } + } + mSyncStorageEngine.restorePeriodicSyncsIfNeededForUser(userId, periodicSyncs); + } + private void onUserUnlocked(int userId) { // Make sure that accounts we're about to use are valid. AccountManagerService.getSingleton().validateAccounts(userId); mSyncAdapters.invalidateCache(userId); + restoreLostPeriodicSyncsIfNeeded(userId); + EndPoint target = new EndPoint(null, null, userId); updateRunningAccounts(target); @@ -2578,9 +2590,11 @@ public class SyncManager { } } + // Cancel all jobs from non-existent accounts. + AccountAndUser[] allAccounts = AccountManagerService.getSingleton().getAllAccounts(); List ops = getAllPendingSyncs(); for (SyncOperation op: ops) { - if (!containsAccountAndUser(accounts, op.target.account, op.target.userId)) { + if (!containsAccountAndUser(allAccounts, op.target.account, op.target.userId)) { getJobScheduler().cancel(op.jobId); } } diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java index bc3fc6a47aef..fb23265c2189 100644 --- a/services/core/java/com/android/server/content/SyncStorageEngine.java +++ b/services/core/java/com/android/server/content/SyncStorageEngine.java @@ -826,6 +826,35 @@ public class SyncStorageEngine extends Handler { return true; } + /** + * STOPSHIP This is a temporary workaround and should be removed before shipping: b/28052438 + */ + void restorePeriodicSyncsIfNeededForUser(int userHandle, List periodicSyncs) { + if (mPeriodicSyncAddedListener == null) { + return; + } + synchronized (mAuthorities) { + for (int i = 0; i < mAuthorities.size(); i++) { + AuthorityInfo authority = mAuthorities.valueAt(i); + if (authority.target.userId == userHandle && authority.enabled) { + boolean periodicSyncAlreadyExists = false; + for (SyncOperation sync : periodicSyncs) { + if (authority.target.matchesSpec(sync.target)) { + periodicSyncAlreadyExists = true; + break; + } + } + // The periodic sync must have been lost due to previous bug. + if (!periodicSyncAlreadyExists) { + mPeriodicSyncAddedListener.onPeriodicSyncAdded(authority.target, + new Bundle(), DEFAULT_POLL_FREQUENCY_SECONDS, + calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS)); + } + } + } + } + } + public void setMasterSyncAutomatically(boolean flag, int userId) { synchronized (mAuthorities) { Boolean auto = mMasterSyncAutomatically.get(userId); -- 2.11.0