diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index e5342ceec1dc0..db41a54f1a0a2 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 bc3fc6a47aef7..fb23265c21898 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);