Loading core/java/android/content/SyncManager.java +45 −14 Original line number Diff line number Diff line Loading @@ -205,6 +205,9 @@ public class SyncManager implements OnAccountsUpdateListener { private final PowerManager mPowerManager; // Use this as a random offset to seed all periodic syncs private int mSyncRandomOffsetMillis; private static final long SYNC_ALARM_TIMEOUT_MIN = 30 * 1000; // 30 seconds private static final long SYNC_ALARM_TIMEOUT_MAX = 2 * 60 * 60 * 1000; // two hours Loading Loading @@ -438,6 +441,9 @@ public class SyncManager implements OnAccountsUpdateListener { // do this synchronously to ensure we have the accounts before this call returns onAccountsUpdated(null); } // Pick a random second in a day to seed all periodic syncs mSyncRandomOffsetMillis = mSyncStorageEngine.getSyncRandomOffset() * 1000; } /** Loading Loading @@ -666,6 +672,7 @@ public class SyncManager implements OnAccountsUpdateListener { private void sendCheckAlarmsMessage() { if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_CHECK_ALARMS"); mSyncHandler.removeMessages(SyncHandler.MESSAGE_CHECK_ALARMS); mSyncHandler.sendEmptyMessage(SyncHandler.MESSAGE_CHECK_ALARMS); } Loading Loading @@ -714,6 +721,8 @@ public class SyncManager implements OnAccountsUpdateListener { } private void increaseBackoffSetting(SyncOperation op) { // TODO: Use this function to align it to an already scheduled sync // operation in the specified window final long now = SystemClock.elapsedRealtime(); final Pair<Long, Long> previousSettings = Loading Loading @@ -1060,6 +1069,8 @@ public class SyncManager implements OnAccountsUpdateListener { final long now = SystemClock.elapsedRealtime(); pw.print("now: "); pw.print(now); pw.println(" (" + formatTime(System.currentTimeMillis()) + ")"); pw.print("offset: "); pw.print(DateUtils.formatElapsedTime(mSyncRandomOffsetMillis/1000)); pw.println(" (HH:MM:SS)"); pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now/1000)); pw.println(" (HH:MM:SS)"); pw.print("time spent syncing: "); Loading Loading @@ -1771,6 +1782,9 @@ public class SyncManager implements OnAccountsUpdateListener { AccountAndUser[] accounts = mAccounts; final long nowAbsolute = System.currentTimeMillis(); final long shiftedNowAbsolute = (0 < nowAbsolute - mSyncRandomOffsetMillis) ? (nowAbsolute - mSyncRandomOffsetMillis) : 0; ArrayList<SyncStorageEngine.AuthorityInfo> infos = mSyncStorageEngine.getAuthorities(); for (SyncStorageEngine.AuthorityInfo info : infos) { // skip the sync if the account of this operation no longer exists Loading @@ -1792,16 +1806,32 @@ public class SyncManager implements OnAccountsUpdateListener { SyncStatusInfo status = mSyncStorageEngine.getOrCreateSyncStatus(info); for (int i = 0, N = info.periodicSyncs.size(); i < N; i++) { final Bundle extras = info.periodicSyncs.get(i).first; final Long periodInSeconds = info.periodicSyncs.get(i).second; final Long periodInMillis = info.periodicSyncs.get(i).second * 1000; // find when this periodic sync was last scheduled to run final long lastPollTimeAbsolute = status.getPeriodicSyncTime(i); // compute when this periodic sync should next run - this can be in the future // for example if the user changed the time, synced and changed back. final long nextPollTimeAbsolute = lastPollTimeAbsolute > nowAbsolute ? nowAbsolute : lastPollTimeAbsolute + periodInSeconds * 1000; // if it is ready to run then schedule it and mark it as having been scheduled if (nextPollTimeAbsolute <= nowAbsolute) { long remainingMillis = periodInMillis - (shiftedNowAbsolute % periodInMillis); /* * Sync scheduling strategy: * Set the next periodic sync based on a random offset (in seconds). * * Also sync right now if any of the following cases hold * and mark it as having been scheduled * * Case 1: This sync is ready to run now. * Case 2: If the lastPollTimeAbsolute is in the future, * sync now and reinitialize. This can happen for * example if the user changed the time, synced and * changed back. * Case 3: If we failed to sync at the last scheduled time */ if (remainingMillis == periodInMillis // Case 1 || lastPollTimeAbsolute > nowAbsolute // Case 2 || (nowAbsolute - lastPollTimeAbsolute >= periodInMillis)) { // Case 3 // Sync now final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff( info.account, info.userId, info.authority); final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo = Loading @@ -1819,15 +1849,16 @@ public class SyncManager implements OnAccountsUpdateListener { info.account, info.userId, info.authority), syncAdapterInfo.type.allowParallelSyncs())); status.setPeriodicSyncTime(i, nowAbsolute); } else { // it isn't ready to run, remember this time if it is earlier than // earliestFuturePollTime } // Compute when this periodic sync should next run final long nextPollTimeAbsolute = nowAbsolute + remainingMillis; // remember this time if it is earlier than earliestFuturePollTime if (nextPollTimeAbsolute < earliestFuturePollTime) { earliestFuturePollTime = nextPollTimeAbsolute; } } } } if (earliestFuturePollTime == Long.MAX_VALUE) { return Long.MAX_VALUE; Loading core/java/android/content/SyncStorageEngine.java +20 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.os.Message; import android.os.Parcel; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; import android.util.SparseArray; import android.util.Xml; Loading @@ -49,6 +50,7 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.Iterator; import java.util.Random; import java.util.TimeZone; import java.util.List; Loading @@ -65,6 +67,7 @@ public class SyncStorageEngine extends Handler { private static final String XML_ATTR_NEXT_AUTHORITY_ID = "nextAuthorityId"; private static final String XML_ATTR_LISTEN_FOR_TICKLES = "listen-for-tickles"; private static final String XML_ATTR_SYNC_RANDOM_OFFSET = "offsetInSeconds"; private static final String XML_ATTR_ENABLED = "enabled"; private static final String XML_ATTR_USER = "user"; private static final String XML_TAG_LISTEN_FOR_TICKLES = "listenForTickles"; Loading Loading @@ -277,6 +280,8 @@ public class SyncStorageEngine extends Handler { private static volatile SyncStorageEngine sSyncStorageEngine = null; private int mSyncRandomOffset; /** * This file contains the core engine state: all accounts and the * settings for them. It must never be lost, and should be changed Loading Loading @@ -375,6 +380,10 @@ public class SyncStorageEngine extends Handler { } } public int getSyncRandomOffset() { return mSyncRandomOffset; } public void addStatusChangeListener(int mask, ISyncStatusObserver callback) { synchronized (mAuthorities) { mChangeListeners.register(callback, mask); Loading Loading @@ -1465,6 +1474,16 @@ public class SyncStorageEngine extends Handler { } catch (NumberFormatException e) { // don't care } String offsetString = parser.getAttributeValue(null, XML_ATTR_SYNC_RANDOM_OFFSET); try { mSyncRandomOffset = (offsetString == null) ? 0 : Integer.parseInt(offsetString); } catch (NumberFormatException e) { mSyncRandomOffset = 0; } if (mSyncRandomOffset == 0) { Random random = new Random(System.currentTimeMillis()); mSyncRandomOffset = random.nextInt(86400); } mMasterSyncAutomatically.put(0, listen == null || Boolean.parseBoolean(listen)); eventType = parser.next(); AuthorityInfo authority = null; Loading Loading @@ -1705,6 +1724,7 @@ public class SyncStorageEngine extends Handler { out.startTag(null, "accounts"); out.attribute(null, "version", Integer.toString(ACCOUNTS_VERSION)); out.attribute(null, XML_ATTR_NEXT_AUTHORITY_ID, Integer.toString(mNextAuthorityId)); out.attribute(null, XML_ATTR_SYNC_RANDOM_OFFSET, Integer.toString(mSyncRandomOffset)); // Write the Sync Automatically flags for each user final int M = mMasterSyncAutomatically.size(); Loading Loading
core/java/android/content/SyncManager.java +45 −14 Original line number Diff line number Diff line Loading @@ -205,6 +205,9 @@ public class SyncManager implements OnAccountsUpdateListener { private final PowerManager mPowerManager; // Use this as a random offset to seed all periodic syncs private int mSyncRandomOffsetMillis; private static final long SYNC_ALARM_TIMEOUT_MIN = 30 * 1000; // 30 seconds private static final long SYNC_ALARM_TIMEOUT_MAX = 2 * 60 * 60 * 1000; // two hours Loading Loading @@ -438,6 +441,9 @@ public class SyncManager implements OnAccountsUpdateListener { // do this synchronously to ensure we have the accounts before this call returns onAccountsUpdated(null); } // Pick a random second in a day to seed all periodic syncs mSyncRandomOffsetMillis = mSyncStorageEngine.getSyncRandomOffset() * 1000; } /** Loading Loading @@ -666,6 +672,7 @@ public class SyncManager implements OnAccountsUpdateListener { private void sendCheckAlarmsMessage() { if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_CHECK_ALARMS"); mSyncHandler.removeMessages(SyncHandler.MESSAGE_CHECK_ALARMS); mSyncHandler.sendEmptyMessage(SyncHandler.MESSAGE_CHECK_ALARMS); } Loading Loading @@ -714,6 +721,8 @@ public class SyncManager implements OnAccountsUpdateListener { } private void increaseBackoffSetting(SyncOperation op) { // TODO: Use this function to align it to an already scheduled sync // operation in the specified window final long now = SystemClock.elapsedRealtime(); final Pair<Long, Long> previousSettings = Loading Loading @@ -1060,6 +1069,8 @@ public class SyncManager implements OnAccountsUpdateListener { final long now = SystemClock.elapsedRealtime(); pw.print("now: "); pw.print(now); pw.println(" (" + formatTime(System.currentTimeMillis()) + ")"); pw.print("offset: "); pw.print(DateUtils.formatElapsedTime(mSyncRandomOffsetMillis/1000)); pw.println(" (HH:MM:SS)"); pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now/1000)); pw.println(" (HH:MM:SS)"); pw.print("time spent syncing: "); Loading Loading @@ -1771,6 +1782,9 @@ public class SyncManager implements OnAccountsUpdateListener { AccountAndUser[] accounts = mAccounts; final long nowAbsolute = System.currentTimeMillis(); final long shiftedNowAbsolute = (0 < nowAbsolute - mSyncRandomOffsetMillis) ? (nowAbsolute - mSyncRandomOffsetMillis) : 0; ArrayList<SyncStorageEngine.AuthorityInfo> infos = mSyncStorageEngine.getAuthorities(); for (SyncStorageEngine.AuthorityInfo info : infos) { // skip the sync if the account of this operation no longer exists Loading @@ -1792,16 +1806,32 @@ public class SyncManager implements OnAccountsUpdateListener { SyncStatusInfo status = mSyncStorageEngine.getOrCreateSyncStatus(info); for (int i = 0, N = info.periodicSyncs.size(); i < N; i++) { final Bundle extras = info.periodicSyncs.get(i).first; final Long periodInSeconds = info.periodicSyncs.get(i).second; final Long periodInMillis = info.periodicSyncs.get(i).second * 1000; // find when this periodic sync was last scheduled to run final long lastPollTimeAbsolute = status.getPeriodicSyncTime(i); // compute when this periodic sync should next run - this can be in the future // for example if the user changed the time, synced and changed back. final long nextPollTimeAbsolute = lastPollTimeAbsolute > nowAbsolute ? nowAbsolute : lastPollTimeAbsolute + periodInSeconds * 1000; // if it is ready to run then schedule it and mark it as having been scheduled if (nextPollTimeAbsolute <= nowAbsolute) { long remainingMillis = periodInMillis - (shiftedNowAbsolute % periodInMillis); /* * Sync scheduling strategy: * Set the next periodic sync based on a random offset (in seconds). * * Also sync right now if any of the following cases hold * and mark it as having been scheduled * * Case 1: This sync is ready to run now. * Case 2: If the lastPollTimeAbsolute is in the future, * sync now and reinitialize. This can happen for * example if the user changed the time, synced and * changed back. * Case 3: If we failed to sync at the last scheduled time */ if (remainingMillis == periodInMillis // Case 1 || lastPollTimeAbsolute > nowAbsolute // Case 2 || (nowAbsolute - lastPollTimeAbsolute >= periodInMillis)) { // Case 3 // Sync now final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff( info.account, info.userId, info.authority); final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo = Loading @@ -1819,15 +1849,16 @@ public class SyncManager implements OnAccountsUpdateListener { info.account, info.userId, info.authority), syncAdapterInfo.type.allowParallelSyncs())); status.setPeriodicSyncTime(i, nowAbsolute); } else { // it isn't ready to run, remember this time if it is earlier than // earliestFuturePollTime } // Compute when this periodic sync should next run final long nextPollTimeAbsolute = nowAbsolute + remainingMillis; // remember this time if it is earlier than earliestFuturePollTime if (nextPollTimeAbsolute < earliestFuturePollTime) { earliestFuturePollTime = nextPollTimeAbsolute; } } } } if (earliestFuturePollTime == Long.MAX_VALUE) { return Long.MAX_VALUE; Loading
core/java/android/content/SyncStorageEngine.java +20 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.os.Message; import android.os.Parcel; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; import android.util.SparseArray; import android.util.Xml; Loading @@ -49,6 +50,7 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.Iterator; import java.util.Random; import java.util.TimeZone; import java.util.List; Loading @@ -65,6 +67,7 @@ public class SyncStorageEngine extends Handler { private static final String XML_ATTR_NEXT_AUTHORITY_ID = "nextAuthorityId"; private static final String XML_ATTR_LISTEN_FOR_TICKLES = "listen-for-tickles"; private static final String XML_ATTR_SYNC_RANDOM_OFFSET = "offsetInSeconds"; private static final String XML_ATTR_ENABLED = "enabled"; private static final String XML_ATTR_USER = "user"; private static final String XML_TAG_LISTEN_FOR_TICKLES = "listenForTickles"; Loading Loading @@ -277,6 +280,8 @@ public class SyncStorageEngine extends Handler { private static volatile SyncStorageEngine sSyncStorageEngine = null; private int mSyncRandomOffset; /** * This file contains the core engine state: all accounts and the * settings for them. It must never be lost, and should be changed Loading Loading @@ -375,6 +380,10 @@ public class SyncStorageEngine extends Handler { } } public int getSyncRandomOffset() { return mSyncRandomOffset; } public void addStatusChangeListener(int mask, ISyncStatusObserver callback) { synchronized (mAuthorities) { mChangeListeners.register(callback, mask); Loading Loading @@ -1465,6 +1474,16 @@ public class SyncStorageEngine extends Handler { } catch (NumberFormatException e) { // don't care } String offsetString = parser.getAttributeValue(null, XML_ATTR_SYNC_RANDOM_OFFSET); try { mSyncRandomOffset = (offsetString == null) ? 0 : Integer.parseInt(offsetString); } catch (NumberFormatException e) { mSyncRandomOffset = 0; } if (mSyncRandomOffset == 0) { Random random = new Random(System.currentTimeMillis()); mSyncRandomOffset = random.nextInt(86400); } mMasterSyncAutomatically.put(0, listen == null || Boolean.parseBoolean(listen)); eventType = parser.next(); AuthorityInfo authority = null; Loading Loading @@ -1705,6 +1724,7 @@ public class SyncStorageEngine extends Handler { out.startTag(null, "accounts"); out.attribute(null, "version", Integer.toString(ACCOUNTS_VERSION)); out.attribute(null, XML_ATTR_NEXT_AUTHORITY_ID, Integer.toString(mNextAuthorityId)); out.attribute(null, XML_ATTR_SYNC_RANDOM_OFFSET, Integer.toString(mSyncRandomOffset)); // Write the Sync Automatically flags for each user final int M = mMasterSyncAutomatically.size(); Loading