Loading apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java +0 −8 Original line number Original line Diff line number Diff line Loading @@ -17,23 +17,15 @@ package com.android.server.job; package com.android.server.job; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.job.JobInfo; import android.app.job.JobParameters; import android.app.job.JobParameters; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream; import java.util.List; /** /** * JobScheduler local system service interface. * JobScheduler local system service interface. * {@hide} Only for use within the system server. * {@hide} Only for use within the system server. */ */ public interface JobSchedulerInternal { public interface JobSchedulerInternal { /** * Returns a list of pending jobs scheduled by the system service. */ List<JobInfo> getSystemScheduledPendingJobs(); /** /** * Cancel the jobs for a given uid (e.g. when app data is cleared) * Cancel the jobs for a given uid (e.g. when app data is cleared) * * Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +0 −17 Original line number Original line Diff line number Diff line Loading @@ -3478,23 +3478,6 @@ public class JobSchedulerService extends com.android.server.SystemService final class LocalService implements JobSchedulerInternal { final class LocalService implements JobSchedulerInternal { /** * Returns a list of all pending jobs. A running job is not considered pending. Periodic * jobs are always considered pending. */ @Override public List<JobInfo> getSystemScheduledPendingJobs() { synchronized (mLock) { final List<JobInfo> pendingJobs = new ArrayList<JobInfo>(); mJobs.forEachJob(Process.SYSTEM_UID, (job) -> { if (job.getJob().isPeriodic() || !mConcurrencyManager.isJobRunningLocked(job)) { pendingJobs.add(job.getJob()); } }); return pendingJobs; } } @Override @Override public void cancelJobsForUid(int uid, boolean includeProxiedJobs, public void cancelJobsForUid(int uid, boolean includeProxiedJobs, @JobParameters.StopReason int reason, int internalReasonCode, String debugReason) { @JobParameters.StopReason int reason, int internalReasonCode, String debugReason) { Loading core/proto/android/server/syncstorageengine.proto +2 −0 Original line number Original line Diff line number Diff line Loading @@ -83,4 +83,6 @@ message SyncStatusProto { } } repeated StatusInfo status = 1; repeated StatusInfo status = 1; optional bool is_job_namespace_migrated = 2; } } services/core/java/com/android/server/content/SyncManager.java +52 −32 Original line number Original line Diff line number Diff line Loading @@ -206,13 +206,6 @@ public class SyncManager { */ */ private static final long SYNC_DELAY_ON_CONFLICT = 10*1000; // 10 seconds private static final long SYNC_DELAY_ON_CONFLICT = 10*1000; // 10 seconds /** * Generate job ids in the range [MIN_SYNC_JOB_ID, MAX_SYNC_JOB_ID) to avoid conflicts with * other jobs scheduled by the system process. */ private static final int MIN_SYNC_JOB_ID = 100000; private static final int MAX_SYNC_JOB_ID = 110000; private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*/"; private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*/"; private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm"; private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm"; private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock"; private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock"; Loading Loading @@ -243,12 +236,11 @@ public class SyncManager { volatile private PowerManager.WakeLock mSyncManagerWakeLock; volatile private PowerManager.WakeLock mSyncManagerWakeLock; volatile private boolean mDataConnectionIsConnected = false; volatile private boolean mDataConnectionIsConnected = false; private volatile int mNextJobIdOffset = 0; private volatile int mNextJobId = 0; private final NotificationManager mNotificationMgr; private final NotificationManager mNotificationMgr; private final IBatteryStats mBatteryStats; private final IBatteryStats mBatteryStats; private JobScheduler mJobScheduler; private JobScheduler mJobScheduler; private JobSchedulerInternal mJobSchedulerInternal; private SyncStorageEngine mSyncStorageEngine; private SyncStorageEngine mSyncStorageEngine; Loading Loading @@ -284,24 +276,19 @@ public class SyncManager { } } private int getUnusedJobIdH() { private int getUnusedJobIdH() { final int maxNumSyncJobIds = MAX_SYNC_JOB_ID - MIN_SYNC_JOB_ID; final List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs(); final List<JobInfo> pendingJobs = mJobSchedulerInternal.getSystemScheduledPendingJobs(); while (isJobIdInUseLockedH(mNextJobId, pendingJobs)) { for (int i = 0; i < maxNumSyncJobIds; ++i) { // SyncManager jobs are placed in their own namespace. Since there's no chance of int newJobId = MIN_SYNC_JOB_ID + ((mNextJobIdOffset + i) % maxNumSyncJobIds); // conflicting with other parts of the system, we can just keep incrementing until if (!isJobIdInUseLockedH(newJobId, pendingJobs)) { // we find an unused ID. mNextJobIdOffset = (mNextJobIdOffset + i + 1) % maxNumSyncJobIds; mNextJobId++; return newJobId; } } } return mNextJobId; // We've used all 10,000 intended job IDs.... We're probably in a world of pain right now :/ Slog.wtf(TAG, "All " + maxNumSyncJobIds + " possible sync job IDs are taken :/"); mNextJobIdOffset = (mNextJobIdOffset + 1) % maxNumSyncJobIds; return MIN_SYNC_JOB_ID + mNextJobIdOffset; } } private List<SyncOperation> getAllPendingSyncs() { private List<SyncOperation> getAllPendingSyncs() { verifyJobScheduler(); verifyJobScheduler(); List<JobInfo> pendingJobs = mJobSchedulerInternal.getSystemScheduledPendingJobs(); List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs(); final int numJobs = pendingJobs.size(); final int numJobs = pendingJobs.size(); final List<SyncOperation> pendingSyncs = new ArrayList<>(numJobs); final List<SyncOperation> pendingSyncs = new ArrayList<>(numJobs); for (int i = 0; i < numJobs; ++i) { for (int i = 0; i < numJobs; ++i) { Loading @@ -309,6 +296,8 @@ public class SyncManager { SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras()); SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras()); if (op != null) { if (op != null) { pendingSyncs.add(op); pendingSyncs.add(op); } else { Slog.wtf(TAG, "Non-sync job inside of SyncManager's namespace"); } } } } return pendingSyncs; return pendingSyncs; Loading Loading @@ -494,6 +483,38 @@ public class SyncManager { }); }); } } /** * Migrate syncs from the default job namespace to SyncManager's namespace if they haven't been * migrated already. */ private void migrateSyncJobNamespaceIfNeeded() { if (mSyncStorageEngine.isJobNamespaceMigrated()) { return; } final JobScheduler jobSchedulerDefaultNamespace = mContext.getSystemService(JobScheduler.class); final List<JobInfo> pendingJobs = jobSchedulerDefaultNamespace.getAllPendingJobs(); // Wait until we've confirmed that all syncs have been migrated to the new namespace // before we persist successful migration to our status file. This is done to avoid // internal consistency issues if the devices reboots right after SyncManager has // done the migration on its side but before JobScheduler has finished persisting // the updated jobs to disk. If JobScheduler hasn't persisted the update to disk, // then nothing that happened afterwards should have been persisted either, so there's // no concern over activity happening after the migration causing issues. boolean allSyncsMigrated = true; for (int i = pendingJobs.size() - 1; i >= 0; --i) { final JobInfo job = pendingJobs.get(i); final SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras()); if (op != null) { // This is a sync. Move it over to SyncManager's namespace. mJobScheduler.schedule(job); jobSchedulerDefaultNamespace.cancel(job.getId()); allSyncsMigrated = false; } } mSyncStorageEngine.setJobNamespaceMigrated(allSyncsMigrated); } private synchronized void verifyJobScheduler() { private synchronized void verifyJobScheduler() { if (mJobScheduler != null) { if (mJobScheduler != null) { return; return; Loading @@ -503,10 +524,12 @@ public class SyncManager { if (Log.isLoggable(TAG, Log.VERBOSE)) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.d(TAG, "initializing JobScheduler object."); Log.d(TAG, "initializing JobScheduler object."); } } mJobScheduler = (JobScheduler) mContext.getSystemService( // Use a dedicated namespace to avoid conflicts with other jobs Context.JOB_SCHEDULER_SERVICE); // scheduled by the system process. mJobSchedulerInternal = getJobSchedulerInternal(); mJobScheduler = mContext.getSystemService(JobScheduler.class) // Get all persisted syncs from JobScheduler .forNamespace("SyncManager"); migrateSyncJobNamespaceIfNeeded(); // Get all persisted syncs from JobScheduler in the SyncManager namespace. List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs(); List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs(); int numPersistedPeriodicSyncs = 0; int numPersistedPeriodicSyncs = 0; Loading @@ -522,6 +545,8 @@ public class SyncManager { // shown on the settings activity. // shown on the settings activity. mSyncStorageEngine.markPending(op.target, true); mSyncStorageEngine.markPending(op.target, true); } } } else { Slog.wtf(TAG, "Non-sync job inside of SyncManager namespace"); } } } } final String summary = "Loaded persisted syncs: " final String summary = "Loaded persisted syncs: " Loading @@ -543,11 +568,6 @@ public class SyncManager { } } } } @VisibleForTesting protected JobSchedulerInternal getJobSchedulerInternal() { return LocalServices.getService(JobSchedulerInternal.class); } /** /** * @return whether the device most likely has some periodic syncs. * @return whether the device most likely has some periodic syncs. */ */ Loading services/core/java/com/android/server/content/SyncStorageEngine.java +23 −1 Original line number Original line Diff line number Diff line Loading @@ -172,6 +172,8 @@ public class SyncStorageEngine { private volatile boolean mIsClockValid; private volatile boolean mIsClockValid; private volatile boolean mIsJobNamespaceMigrated; static { static { sAuthorityRenames = new HashMap<String, String>(); sAuthorityRenames = new HashMap<String, String>(); sAuthorityRenames.put("contacts", "com.android.contacts"); sAuthorityRenames.put("contacts", "com.android.contacts"); Loading Loading @@ -836,6 +838,20 @@ public class SyncStorageEngine { reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, target); reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, target); } } void setJobNamespaceMigrated(boolean migrated) { if (mIsJobNamespaceMigrated == migrated) { return; } mIsJobNamespaceMigrated = migrated; // This isn't urgent enough to write synchronously. Post it to the handler thread so // SyncManager can move on with whatever it was doing. mHandler.sendEmptyMessageDelayed(MSG_WRITE_STATUS, WRITE_STATUS_DELAY); } boolean isJobNamespaceMigrated() { return mIsJobNamespaceMigrated; } public Pair<Long, Long> getBackoff(EndPoint info) { public Pair<Long, Long> getBackoff(EndPoint info) { synchronized (mAuthorities) { synchronized (mAuthorities) { AuthorityInfo authority = getAuthorityLocked(info, "getBackoff"); AuthorityInfo authority = getAuthorityLocked(info, "getBackoff"); Loading Loading @@ -1585,7 +1601,6 @@ public class SyncStorageEngine { } } } } /** /** * Remove an authority associated with a provider. Needs to be a standalone function for * Remove an authority associated with a provider. Needs to be a standalone function for * backward compatibility. * backward compatibility. Loading Loading @@ -2101,6 +2116,10 @@ public class SyncStorageEngine { mSyncStatus.put(status.authorityId, status); mSyncStatus.put(status.authorityId, status); } } break; break; case (int) SyncStatusProto.IS_JOB_NAMESPACE_MIGRATED: mIsJobNamespaceMigrated = proto.readBoolean(SyncStatusProto.IS_JOB_NAMESPACE_MIGRATED); break; case ProtoInputStream.NO_MORE_FIELDS: case ProtoInputStream.NO_MORE_FIELDS: return; return; } } Loading Loading @@ -2368,6 +2387,9 @@ public class SyncStorageEngine { } } proto.end(token); proto.end(token); } } proto.write(SyncStatusProto.IS_JOB_NAMESPACE_MIGRATED, mIsJobNamespaceMigrated); proto.flush(); proto.flush(); } } Loading Loading
apex/jobscheduler/framework/java/com/android/server/job/JobSchedulerInternal.java +0 −8 Original line number Original line Diff line number Diff line Loading @@ -17,23 +17,15 @@ package com.android.server.job; package com.android.server.job; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.job.JobInfo; import android.app.job.JobParameters; import android.app.job.JobParameters; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream; import java.util.List; /** /** * JobScheduler local system service interface. * JobScheduler local system service interface. * {@hide} Only for use within the system server. * {@hide} Only for use within the system server. */ */ public interface JobSchedulerInternal { public interface JobSchedulerInternal { /** * Returns a list of pending jobs scheduled by the system service. */ List<JobInfo> getSystemScheduledPendingJobs(); /** /** * Cancel the jobs for a given uid (e.g. when app data is cleared) * Cancel the jobs for a given uid (e.g. when app data is cleared) * * Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +0 −17 Original line number Original line Diff line number Diff line Loading @@ -3478,23 +3478,6 @@ public class JobSchedulerService extends com.android.server.SystemService final class LocalService implements JobSchedulerInternal { final class LocalService implements JobSchedulerInternal { /** * Returns a list of all pending jobs. A running job is not considered pending. Periodic * jobs are always considered pending. */ @Override public List<JobInfo> getSystemScheduledPendingJobs() { synchronized (mLock) { final List<JobInfo> pendingJobs = new ArrayList<JobInfo>(); mJobs.forEachJob(Process.SYSTEM_UID, (job) -> { if (job.getJob().isPeriodic() || !mConcurrencyManager.isJobRunningLocked(job)) { pendingJobs.add(job.getJob()); } }); return pendingJobs; } } @Override @Override public void cancelJobsForUid(int uid, boolean includeProxiedJobs, public void cancelJobsForUid(int uid, boolean includeProxiedJobs, @JobParameters.StopReason int reason, int internalReasonCode, String debugReason) { @JobParameters.StopReason int reason, int internalReasonCode, String debugReason) { Loading
core/proto/android/server/syncstorageengine.proto +2 −0 Original line number Original line Diff line number Diff line Loading @@ -83,4 +83,6 @@ message SyncStatusProto { } } repeated StatusInfo status = 1; repeated StatusInfo status = 1; optional bool is_job_namespace_migrated = 2; } }
services/core/java/com/android/server/content/SyncManager.java +52 −32 Original line number Original line Diff line number Diff line Loading @@ -206,13 +206,6 @@ public class SyncManager { */ */ private static final long SYNC_DELAY_ON_CONFLICT = 10*1000; // 10 seconds private static final long SYNC_DELAY_ON_CONFLICT = 10*1000; // 10 seconds /** * Generate job ids in the range [MIN_SYNC_JOB_ID, MAX_SYNC_JOB_ID) to avoid conflicts with * other jobs scheduled by the system process. */ private static final int MIN_SYNC_JOB_ID = 100000; private static final int MAX_SYNC_JOB_ID = 110000; private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*/"; private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*/"; private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm"; private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm"; private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock"; private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock"; Loading Loading @@ -243,12 +236,11 @@ public class SyncManager { volatile private PowerManager.WakeLock mSyncManagerWakeLock; volatile private PowerManager.WakeLock mSyncManagerWakeLock; volatile private boolean mDataConnectionIsConnected = false; volatile private boolean mDataConnectionIsConnected = false; private volatile int mNextJobIdOffset = 0; private volatile int mNextJobId = 0; private final NotificationManager mNotificationMgr; private final NotificationManager mNotificationMgr; private final IBatteryStats mBatteryStats; private final IBatteryStats mBatteryStats; private JobScheduler mJobScheduler; private JobScheduler mJobScheduler; private JobSchedulerInternal mJobSchedulerInternal; private SyncStorageEngine mSyncStorageEngine; private SyncStorageEngine mSyncStorageEngine; Loading Loading @@ -284,24 +276,19 @@ public class SyncManager { } } private int getUnusedJobIdH() { private int getUnusedJobIdH() { final int maxNumSyncJobIds = MAX_SYNC_JOB_ID - MIN_SYNC_JOB_ID; final List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs(); final List<JobInfo> pendingJobs = mJobSchedulerInternal.getSystemScheduledPendingJobs(); while (isJobIdInUseLockedH(mNextJobId, pendingJobs)) { for (int i = 0; i < maxNumSyncJobIds; ++i) { // SyncManager jobs are placed in their own namespace. Since there's no chance of int newJobId = MIN_SYNC_JOB_ID + ((mNextJobIdOffset + i) % maxNumSyncJobIds); // conflicting with other parts of the system, we can just keep incrementing until if (!isJobIdInUseLockedH(newJobId, pendingJobs)) { // we find an unused ID. mNextJobIdOffset = (mNextJobIdOffset + i + 1) % maxNumSyncJobIds; mNextJobId++; return newJobId; } } } return mNextJobId; // We've used all 10,000 intended job IDs.... We're probably in a world of pain right now :/ Slog.wtf(TAG, "All " + maxNumSyncJobIds + " possible sync job IDs are taken :/"); mNextJobIdOffset = (mNextJobIdOffset + 1) % maxNumSyncJobIds; return MIN_SYNC_JOB_ID + mNextJobIdOffset; } } private List<SyncOperation> getAllPendingSyncs() { private List<SyncOperation> getAllPendingSyncs() { verifyJobScheduler(); verifyJobScheduler(); List<JobInfo> pendingJobs = mJobSchedulerInternal.getSystemScheduledPendingJobs(); List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs(); final int numJobs = pendingJobs.size(); final int numJobs = pendingJobs.size(); final List<SyncOperation> pendingSyncs = new ArrayList<>(numJobs); final List<SyncOperation> pendingSyncs = new ArrayList<>(numJobs); for (int i = 0; i < numJobs; ++i) { for (int i = 0; i < numJobs; ++i) { Loading @@ -309,6 +296,8 @@ public class SyncManager { SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras()); SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras()); if (op != null) { if (op != null) { pendingSyncs.add(op); pendingSyncs.add(op); } else { Slog.wtf(TAG, "Non-sync job inside of SyncManager's namespace"); } } } } return pendingSyncs; return pendingSyncs; Loading Loading @@ -494,6 +483,38 @@ public class SyncManager { }); }); } } /** * Migrate syncs from the default job namespace to SyncManager's namespace if they haven't been * migrated already. */ private void migrateSyncJobNamespaceIfNeeded() { if (mSyncStorageEngine.isJobNamespaceMigrated()) { return; } final JobScheduler jobSchedulerDefaultNamespace = mContext.getSystemService(JobScheduler.class); final List<JobInfo> pendingJobs = jobSchedulerDefaultNamespace.getAllPendingJobs(); // Wait until we've confirmed that all syncs have been migrated to the new namespace // before we persist successful migration to our status file. This is done to avoid // internal consistency issues if the devices reboots right after SyncManager has // done the migration on its side but before JobScheduler has finished persisting // the updated jobs to disk. If JobScheduler hasn't persisted the update to disk, // then nothing that happened afterwards should have been persisted either, so there's // no concern over activity happening after the migration causing issues. boolean allSyncsMigrated = true; for (int i = pendingJobs.size() - 1; i >= 0; --i) { final JobInfo job = pendingJobs.get(i); final SyncOperation op = SyncOperation.maybeCreateFromJobExtras(job.getExtras()); if (op != null) { // This is a sync. Move it over to SyncManager's namespace. mJobScheduler.schedule(job); jobSchedulerDefaultNamespace.cancel(job.getId()); allSyncsMigrated = false; } } mSyncStorageEngine.setJobNamespaceMigrated(allSyncsMigrated); } private synchronized void verifyJobScheduler() { private synchronized void verifyJobScheduler() { if (mJobScheduler != null) { if (mJobScheduler != null) { return; return; Loading @@ -503,10 +524,12 @@ public class SyncManager { if (Log.isLoggable(TAG, Log.VERBOSE)) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.d(TAG, "initializing JobScheduler object."); Log.d(TAG, "initializing JobScheduler object."); } } mJobScheduler = (JobScheduler) mContext.getSystemService( // Use a dedicated namespace to avoid conflicts with other jobs Context.JOB_SCHEDULER_SERVICE); // scheduled by the system process. mJobSchedulerInternal = getJobSchedulerInternal(); mJobScheduler = mContext.getSystemService(JobScheduler.class) // Get all persisted syncs from JobScheduler .forNamespace("SyncManager"); migrateSyncJobNamespaceIfNeeded(); // Get all persisted syncs from JobScheduler in the SyncManager namespace. List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs(); List<JobInfo> pendingJobs = mJobScheduler.getAllPendingJobs(); int numPersistedPeriodicSyncs = 0; int numPersistedPeriodicSyncs = 0; Loading @@ -522,6 +545,8 @@ public class SyncManager { // shown on the settings activity. // shown on the settings activity. mSyncStorageEngine.markPending(op.target, true); mSyncStorageEngine.markPending(op.target, true); } } } else { Slog.wtf(TAG, "Non-sync job inside of SyncManager namespace"); } } } } final String summary = "Loaded persisted syncs: " final String summary = "Loaded persisted syncs: " Loading @@ -543,11 +568,6 @@ public class SyncManager { } } } } @VisibleForTesting protected JobSchedulerInternal getJobSchedulerInternal() { return LocalServices.getService(JobSchedulerInternal.class); } /** /** * @return whether the device most likely has some periodic syncs. * @return whether the device most likely has some periodic syncs. */ */ Loading
services/core/java/com/android/server/content/SyncStorageEngine.java +23 −1 Original line number Original line Diff line number Diff line Loading @@ -172,6 +172,8 @@ public class SyncStorageEngine { private volatile boolean mIsClockValid; private volatile boolean mIsClockValid; private volatile boolean mIsJobNamespaceMigrated; static { static { sAuthorityRenames = new HashMap<String, String>(); sAuthorityRenames = new HashMap<String, String>(); sAuthorityRenames.put("contacts", "com.android.contacts"); sAuthorityRenames.put("contacts", "com.android.contacts"); Loading Loading @@ -836,6 +838,20 @@ public class SyncStorageEngine { reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, target); reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, target); } } void setJobNamespaceMigrated(boolean migrated) { if (mIsJobNamespaceMigrated == migrated) { return; } mIsJobNamespaceMigrated = migrated; // This isn't urgent enough to write synchronously. Post it to the handler thread so // SyncManager can move on with whatever it was doing. mHandler.sendEmptyMessageDelayed(MSG_WRITE_STATUS, WRITE_STATUS_DELAY); } boolean isJobNamespaceMigrated() { return mIsJobNamespaceMigrated; } public Pair<Long, Long> getBackoff(EndPoint info) { public Pair<Long, Long> getBackoff(EndPoint info) { synchronized (mAuthorities) { synchronized (mAuthorities) { AuthorityInfo authority = getAuthorityLocked(info, "getBackoff"); AuthorityInfo authority = getAuthorityLocked(info, "getBackoff"); Loading Loading @@ -1585,7 +1601,6 @@ public class SyncStorageEngine { } } } } /** /** * Remove an authority associated with a provider. Needs to be a standalone function for * Remove an authority associated with a provider. Needs to be a standalone function for * backward compatibility. * backward compatibility. Loading Loading @@ -2101,6 +2116,10 @@ public class SyncStorageEngine { mSyncStatus.put(status.authorityId, status); mSyncStatus.put(status.authorityId, status); } } break; break; case (int) SyncStatusProto.IS_JOB_NAMESPACE_MIGRATED: mIsJobNamespaceMigrated = proto.readBoolean(SyncStatusProto.IS_JOB_NAMESPACE_MIGRATED); break; case ProtoInputStream.NO_MORE_FIELDS: case ProtoInputStream.NO_MORE_FIELDS: return; return; } } Loading Loading @@ -2368,6 +2387,9 @@ public class SyncStorageEngine { } } proto.end(token); proto.end(token); } } proto.write(SyncStatusProto.IS_JOB_NAMESPACE_MIGRATED, mIsJobNamespaceMigrated); proto.flush(); proto.flush(); } } Loading