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
This commit is contained in:
Rubin Xu
2016-04-01 17:47:28 +01:00
parent 8da25ef74a
commit 2c548e0e11
2 changed files with 44 additions and 1 deletions

View File

@@ -1402,12 +1402,24 @@ public class SyncManager {
}
}
private void restoreLostPeriodicSyncsIfNeeded(int userId) {
List<SyncOperation> periodicSyncs = new ArrayList<SyncOperation>();
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<SyncOperation> 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);
}
}

View File

@@ -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<SyncOperation> 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);