diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java index 58396eb69d14d..a230b23f03a48 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/BackgroundJobsController.java @@ -17,6 +17,7 @@ package com.android.server.job.controllers; import static com.android.server.job.JobSchedulerService.NEVER_INDEX; +import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.os.SystemClock; import android.os.UserHandle; @@ -59,6 +60,8 @@ public final class BackgroundJobsController extends StateController { private final AppStateTrackerImpl mAppStateTracker; + private final UpdateJobFunctor mUpdateJobFunctor = new UpdateJobFunctor(); + public BackgroundJobsController(JobSchedulerService service) { super(service); @@ -69,7 +72,7 @@ public final class BackgroundJobsController extends StateController { @Override public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) { - updateSingleJobRestrictionLocked(jobStatus, UNKNOWN); + updateSingleJobRestrictionLocked(jobStatus, sElapsedRealtimeClock.millis(), UNKNOWN); } @Override @@ -79,7 +82,7 @@ public final class BackgroundJobsController extends StateController { @Override public void evaluateStateLocked(JobStatus jobStatus) { - updateSingleJobRestrictionLocked(jobStatus, UNKNOWN); + updateSingleJobRestrictionLocked(jobStatus, sElapsedRealtimeClock.millis(), UNKNOWN); } @Override @@ -163,33 +166,34 @@ public final class BackgroundJobsController extends StateController { } private void updateJobRestrictionsLocked(int filterUid, int newActiveState) { - final UpdateJobFunctor updateTrackedJobs = new UpdateJobFunctor(newActiveState); + mUpdateJobFunctor.prepare(newActiveState); final long start = DEBUG ? SystemClock.elapsedRealtimeNanos() : 0; final JobStore store = mService.getJobStore(); if (filterUid > 0) { - store.forEachJobForSourceUid(filterUid, updateTrackedJobs); + store.forEachJobForSourceUid(filterUid, mUpdateJobFunctor); } else { - store.forEachJob(updateTrackedJobs); + store.forEachJob(mUpdateJobFunctor); } final long time = DEBUG ? (SystemClock.elapsedRealtimeNanos() - start) : 0; if (DEBUG) { Slog.d(TAG, String.format( "Job status updated: %d/%d checked/total jobs, %d us", - updateTrackedJobs.mCheckedCount, - updateTrackedJobs.mTotalCount, + mUpdateJobFunctor.mCheckedCount, + mUpdateJobFunctor.mTotalCount, (time / 1000) - )); + )); } - if (updateTrackedJobs.mChanged) { + if (mUpdateJobFunctor.mChanged) { mStateChangedListener.onControllerStateChanged(); } } - boolean updateSingleJobRestrictionLocked(JobStatus jobStatus, int activeState) { + boolean updateSingleJobRestrictionLocked(JobStatus jobStatus, final long nowElapsed, + int activeState) { final int uid = jobStatus.getSourceUid(); final String packageName = jobStatus.getSourcePackageName(); @@ -205,26 +209,32 @@ public final class BackgroundJobsController extends StateController { if (isActive && jobStatus.getStandbyBucket() == NEVER_INDEX) { jobStatus.maybeLogBucketMismatch(); } - boolean didChange = jobStatus.setBackgroundNotRestrictedConstraintSatisfied(canRun); + boolean didChange = + jobStatus.setBackgroundNotRestrictedConstraintSatisfied(nowElapsed, canRun); didChange |= jobStatus.setUidActive(isActive); return didChange; } private final class UpdateJobFunctor implements Consumer { - final int activeState; + int mActiveState; boolean mChanged = false; int mTotalCount = 0; int mCheckedCount = 0; + long mUpdateTimeElapsed = 0; - public UpdateJobFunctor(int newActiveState) { - activeState = newActiveState; + void prepare(int newActiveState) { + mActiveState = newActiveState; + mUpdateTimeElapsed = sElapsedRealtimeClock.millis(); + mChanged = false; + mTotalCount = 0; + mCheckedCount = 0; } @Override public void accept(JobStatus jobStatus) { mTotalCount++; mCheckedCount++; - if (updateSingleJobRestrictionLocked(jobStatus, activeState)) { + if (updateSingleJobRestrictionLocked(jobStatus, mUpdateTimeElapsed, mActiveState)) { mChanged = true; } } diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java index 28269c89d13b9..6fd094844cd63 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/BatteryController.java @@ -65,10 +65,12 @@ public final class BatteryController extends RestrictingController { @Override public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) { if (taskStatus.hasPowerConstraint()) { + final long nowElapsed = sElapsedRealtimeClock.millis(); mTrackedTasks.add(taskStatus); taskStatus.setTrackingController(JobStatus.TRACKING_BATTERY); - taskStatus.setChargingConstraintSatisfied(mChargeTracker.isOnStablePower()); - taskStatus.setBatteryNotLowConstraintSatisfied(mChargeTracker.isBatteryNotLow()); + taskStatus.setChargingConstraintSatisfied(nowElapsed, mChargeTracker.isOnStablePower()); + taskStatus.setBatteryNotLowConstraintSatisfied( + nowElapsed, mChargeTracker.isBatteryNotLow()); } } @@ -97,14 +99,15 @@ public final class BatteryController extends RestrictingController { if (DEBUG) { Slog.d(TAG, "maybeReportNewChargingStateLocked: " + stablePower); } + final long nowElapsed = sElapsedRealtimeClock.millis(); boolean reportChange = false; for (int i = mTrackedTasks.size() - 1; i >= 0; i--) { final JobStatus ts = mTrackedTasks.valueAt(i); - boolean previous = ts.setChargingConstraintSatisfied(stablePower); + boolean previous = ts.setChargingConstraintSatisfied(nowElapsed, stablePower); if (previous != stablePower) { reportChange = true; } - previous = ts.setBatteryNotLowConstraintSatisfied(batteryNotLow); + previous = ts.setBatteryNotLowConstraintSatisfied(nowElapsed, batteryNotLow); if (previous != batteryNotLow) { reportChange = true; } diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java index 14484ff441ca8..6e542f346f818 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java @@ -20,6 +20,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; +import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.annotation.Nullable; import android.app.job.JobInfo; @@ -461,11 +462,12 @@ public final class ConnectivityController extends RestrictingController implemen final Network network = mConnManager.getActiveNetworkForUid( jobStatus.getSourceUid(), jobStatus.shouldIgnoreNetworkBlocking()); final NetworkCapabilities capabilities = getNetworkCapabilities(network); - return updateConstraintsSatisfied(jobStatus, network, capabilities); + return updateConstraintsSatisfied(jobStatus, sElapsedRealtimeClock.millis(), + network, capabilities); } - private boolean updateConstraintsSatisfied(JobStatus jobStatus, Network network, - NetworkCapabilities capabilities) { + private boolean updateConstraintsSatisfied(JobStatus jobStatus, final long nowElapsed, + Network network, NetworkCapabilities capabilities) { // TODO: consider matching against non-active networks final boolean ignoreBlocked = jobStatus.shouldIgnoreNetworkBlocking(); @@ -476,7 +478,7 @@ public final class ConnectivityController extends RestrictingController implemen final boolean satisfied = isSatisfied(jobStatus, network, capabilities, mConstants); final boolean changed = jobStatus - .setConnectivityConstraintSatisfied(connected && satisfied); + .setConnectivityConstraintSatisfied(nowElapsed, connected && satisfied); // Pass along the evaluated network for job to use; prevents race // conditions as default routes change over time, and opens the door to @@ -530,6 +532,7 @@ public final class ConnectivityController extends RestrictingController implemen NetworkCapabilities exemptedNetworkCapabilities = null; boolean exemptedNetworkMatch = false; + final long nowElapsed = sElapsedRealtimeClock.millis(); boolean changed = false; for (int i = jobs.size() - 1; i >= 0; i--) { final JobStatus js = jobs.valueAt(i); @@ -555,7 +558,7 @@ public final class ConnectivityController extends RestrictingController implemen // job hasn't yet been evaluated against the currently // active network; typically when we just lost a network. if (match || !Objects.equals(js.network, net)) { - changed |= updateConstraintsSatisfied(js, net, netCap); + changed |= updateConstraintsSatisfied(js, nowElapsed, net, netCap); } } return changed; diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ContentObserverController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ContentObserverController.java index 131a6d4f47917..8b0da3471781d 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ContentObserverController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ContentObserverController.java @@ -16,6 +16,8 @@ package com.android.server.job.controllers; +import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; + import android.annotation.UserIdInt; import android.app.job.JobInfo; import android.database.ContentObserver; @@ -74,6 +76,7 @@ public final class ContentObserverController extends StateController { @Override public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) { if (taskStatus.hasContentTriggerConstraint()) { + final long nowElapsed = sElapsedRealtimeClock.millis(); if (taskStatus.contentObserverJobInstance == null) { taskStatus.contentObserverJobInstance = new JobInstance(taskStatus); } @@ -110,7 +113,7 @@ public final class ContentObserverController extends StateController { } taskStatus.changedAuthorities = null; taskStatus.changedUris = null; - taskStatus.setContentTriggerConstraintSatisfied(havePendingUris); + taskStatus.setContentTriggerConstraintSatisfied(nowElapsed, havePendingUris); } if (lastJob != null && lastJob.contentObserverJobInstance != null) { // And now we can detach the instance state from the last job. @@ -295,7 +298,8 @@ public final class ContentObserverController extends StateController { boolean reportChange = false; synchronized (mLock) { if (mTriggerPending) { - if (mJobStatus.setContentTriggerConstraintSatisfied(true)) { + final long nowElapsed = sElapsedRealtimeClock.millis(); + if (mJobStatus.setContentTriggerConstraintSatisfied(nowElapsed, true)) { reportChange = true; } unscheduleLocked(); diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java index 04b41646b48ba..192f5e66255d9 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/DeviceIdleJobsController.java @@ -16,6 +16,8 @@ package com.android.server.job.controllers; +import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; + import android.app.job.JobInfo; import android.content.BroadcastReceiver; import android.content.Context; @@ -104,8 +106,10 @@ public final class DeviceIdleJobsController extends StateController { + Arrays.toString(mPowerSaveTempWhitelistAppIds)); } boolean changed = false; + final long nowElapsed = sElapsedRealtimeClock.millis(); for (int i = 0; i < mAllowInIdleJobs.size(); i++) { - changed |= updateTaskStateLocked(mAllowInIdleJobs.valueAt(i)); + changed |= + updateTaskStateLocked(mAllowInIdleJobs.valueAt(i), nowElapsed); } if (changed) { mStateChangedListener.onControllerStateChanged(); @@ -147,6 +151,7 @@ public final class DeviceIdleJobsController extends StateController { } mDeviceIdleMode = enabled; if (DEBUG) Slog.d(TAG, "mDeviceIdleMode=" + mDeviceIdleMode); + mDeviceIdleUpdateFunctor.prepare(); if (enabled) { mHandler.removeMessages(PROCESS_BACKGROUND_JOBS); mService.getJobStore().forEachJob(mDeviceIdleUpdateFunctor); @@ -180,7 +185,7 @@ public final class DeviceIdleJobsController extends StateController { Slog.d(TAG, "uid " + uid + " going " + (active ? "active" : "inactive")); } mForegroundUids.put(uid, active); - mDeviceIdleUpdateFunctor.mChanged = false; + mDeviceIdleUpdateFunctor.prepare(); mService.getJobStore().forEachJobForSourceUid(uid, mDeviceIdleUpdateFunctor); if (mDeviceIdleUpdateFunctor.mChanged) { mStateChangedListener.onControllerStateChanged(); @@ -203,12 +208,12 @@ public final class DeviceIdleJobsController extends StateController { UserHandle.getAppId(job.getSourceUid())); } - private boolean updateTaskStateLocked(JobStatus task) { + private boolean updateTaskStateLocked(JobStatus task, final long nowElapsed) { final boolean allowInIdle = ((task.getFlags()&JobInfo.FLAG_IMPORTANT_WHILE_FOREGROUND) != 0) && (mForegroundUids.get(task.getSourceUid()) || isTempWhitelistedLocked(task)); final boolean whitelisted = isWhitelistedLocked(task); final boolean enableTask = !mDeviceIdleMode || whitelisted || allowInIdle; - return task.setDeviceNotDozingConstraintSatisfied(enableTask, whitelisted); + return task.setDeviceNotDozingConstraintSatisfied(nowElapsed, enableTask, whitelisted); } @Override @@ -216,7 +221,7 @@ public final class DeviceIdleJobsController extends StateController { if ((jobStatus.getFlags()&JobInfo.FLAG_IMPORTANT_WHILE_FOREGROUND) != 0) { mAllowInIdleJobs.add(jobStatus); } - updateTaskStateLocked(jobStatus); + updateTaskStateLocked(jobStatus, sElapsedRealtimeClock.millis()); } @Override @@ -282,10 +287,16 @@ public final class DeviceIdleJobsController extends StateController { final class DeviceIdleUpdateFunctor implements Consumer { boolean mChanged; + long mUpdateTimeElapsed = 0; + + void prepare() { + mChanged = false; + mUpdateTimeElapsed = sElapsedRealtimeClock.millis(); + } @Override public void accept(JobStatus jobStatus) { - mChanged |= updateTaskStateLocked(jobStatus); + mChanged |= updateTaskStateLocked(jobStatus, mUpdateTimeElapsed); } } @@ -300,7 +311,7 @@ public final class DeviceIdleJobsController extends StateController { case PROCESS_BACKGROUND_JOBS: // Just process all the jobs, the ones in foreground should already be running. synchronized (mLock) { - mDeviceIdleUpdateFunctor.mChanged = false; + mDeviceIdleUpdateFunctor.prepare(); mService.getJobStore().forEachJob(mDeviceIdleUpdateFunctor); if (mDeviceIdleUpdateFunctor.mChanged) { mStateChangedListener.onControllerStateChanged(); diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java index 2fe827e338e99..e26a3c6962d59 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java @@ -16,6 +16,8 @@ package com.android.server.job.controllers; +import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; + import android.content.Context; import android.content.pm.PackageManager; import android.os.UserHandle; @@ -58,9 +60,10 @@ public final class IdleController extends RestrictingController implements Idlen @Override public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) { if (taskStatus.hasIdleConstraint()) { + final long nowElapsed = sElapsedRealtimeClock.millis(); mTrackedTasks.add(taskStatus); taskStatus.setTrackingController(JobStatus.TRACKING_IDLE); - taskStatus.setIdleConstraintSatisfied(mIdleTracker.isIdle()); + taskStatus.setIdleConstraintSatisfied(nowElapsed, mIdleTracker.isIdle()); } } @@ -90,8 +93,9 @@ public final class IdleController extends RestrictingController implements Idlen @Override public void reportNewIdleState(boolean isIdle) { synchronized (mLock) { + final long nowElapsed = sElapsedRealtimeClock.millis(); for (int i = mTrackedTasks.size()-1; i >= 0; i--) { - mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(isIdle); + mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(nowElapsed, isIdle); } } mStateChangedListener.onControllerStateChanged(); diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java index 6917fb531ac46..5bdeb38a14245 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java @@ -73,6 +73,8 @@ public final class JobStatus { private static final String TAG = "JobScheduler.JobStatus"; static final boolean DEBUG = JobSchedulerService.DEBUG; + private static final int NUM_CONSTRAINT_CHANGE_HISTORY = 10; + public static final long NO_LATEST_RUNTIME = Long.MAX_VALUE; public static final long NO_EARLIEST_RUNTIME = 0L; @@ -350,6 +352,10 @@ public final class JobStatus { */ private Pair mPersistedUtcTimes; + private int mConstraintChangeHistoryIndex = 0; + private final long[] mConstraintUpdatedTimesElapsed = new long[NUM_CONSTRAINT_CHANGE_HISTORY]; + private final int[] mConstraintStatusHistory = new int[NUM_CONSTRAINT_CHANGE_HISTORY]; + /** * For use only by ContentObserverController: state it is maintaining about content URIs * being observed. @@ -1090,28 +1096,28 @@ public final class JobStatus { } /** @return true if the constraint was changed, false otherwise. */ - boolean setChargingConstraintSatisfied(boolean state) { - return setConstraintSatisfied(CONSTRAINT_CHARGING, state); + boolean setChargingConstraintSatisfied(final long nowElapsed, boolean state) { + return setConstraintSatisfied(CONSTRAINT_CHARGING, nowElapsed, state); } /** @return true if the constraint was changed, false otherwise. */ - boolean setBatteryNotLowConstraintSatisfied(boolean state) { - return setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW, state); + boolean setBatteryNotLowConstraintSatisfied(final long nowElapsed, boolean state) { + return setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW, nowElapsed, state); } /** @return true if the constraint was changed, false otherwise. */ - boolean setStorageNotLowConstraintSatisfied(boolean state) { - return setConstraintSatisfied(CONSTRAINT_STORAGE_NOT_LOW, state); + boolean setStorageNotLowConstraintSatisfied(final long nowElapsed, boolean state) { + return setConstraintSatisfied(CONSTRAINT_STORAGE_NOT_LOW, nowElapsed, state); } /** @return true if the constraint was changed, false otherwise. */ - boolean setTimingDelayConstraintSatisfied(boolean state) { - return setConstraintSatisfied(CONSTRAINT_TIMING_DELAY, state); + boolean setTimingDelayConstraintSatisfied(final long nowElapsed, boolean state) { + return setConstraintSatisfied(CONSTRAINT_TIMING_DELAY, nowElapsed, state); } /** @return true if the constraint was changed, false otherwise. */ - boolean setDeadlineConstraintSatisfied(boolean state) { - if (setConstraintSatisfied(CONSTRAINT_DEADLINE, state)) { + boolean setDeadlineConstraintSatisfied(final long nowElapsed, boolean state) { + if (setConstraintSatisfied(CONSTRAINT_DEADLINE, nowElapsed, state)) { // The constraint was changed. Update the ready flag. mReadyDeadlineSatisfied = !job.isPeriodic() && hasDeadlineConstraint() && state; return true; @@ -1120,24 +1126,25 @@ public final class JobStatus { } /** @return true if the constraint was changed, false otherwise. */ - boolean setIdleConstraintSatisfied(boolean state) { - return setConstraintSatisfied(CONSTRAINT_IDLE, state); + boolean setIdleConstraintSatisfied(final long nowElapsed, boolean state) { + return setConstraintSatisfied(CONSTRAINT_IDLE, nowElapsed, state); } /** @return true if the constraint was changed, false otherwise. */ - boolean setConnectivityConstraintSatisfied(boolean state) { - return setConstraintSatisfied(CONSTRAINT_CONNECTIVITY, state); + boolean setConnectivityConstraintSatisfied(final long nowElapsed, boolean state) { + return setConstraintSatisfied(CONSTRAINT_CONNECTIVITY, nowElapsed, state); } /** @return true if the constraint was changed, false otherwise. */ - boolean setContentTriggerConstraintSatisfied(boolean state) { - return setConstraintSatisfied(CONSTRAINT_CONTENT_TRIGGER, state); + boolean setContentTriggerConstraintSatisfied(final long nowElapsed, boolean state) { + return setConstraintSatisfied(CONSTRAINT_CONTENT_TRIGGER, nowElapsed, state); } /** @return true if the constraint was changed, false otherwise. */ - boolean setDeviceNotDozingConstraintSatisfied(boolean state, boolean whitelisted) { + boolean setDeviceNotDozingConstraintSatisfied(final long nowElapsed, + boolean state, boolean whitelisted) { dozeWhitelisted = whitelisted; - if (setConstraintSatisfied(CONSTRAINT_DEVICE_NOT_DOZING, state)) { + if (setConstraintSatisfied(CONSTRAINT_DEVICE_NOT_DOZING, nowElapsed, state)) { // The constraint was changed. Update the ready flag. mReadyNotDozing = state || canRunInDoze(); return true; @@ -1146,8 +1153,8 @@ public final class JobStatus { } /** @return true if the constraint was changed, false otherwise. */ - boolean setBackgroundNotRestrictedConstraintSatisfied(boolean state) { - if (setConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED, state)) { + boolean setBackgroundNotRestrictedConstraintSatisfied(final long nowElapsed, boolean state) { + if (setConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED, nowElapsed, state)) { // The constraint was changed. Update the ready flag. mReadyNotRestrictedInBg = state; return true; @@ -1156,8 +1163,8 @@ public final class JobStatus { } /** @return true if the constraint was changed, false otherwise. */ - boolean setQuotaConstraintSatisfied(boolean state) { - if (setConstraintSatisfied(CONSTRAINT_WITHIN_QUOTA, state)) { + boolean setQuotaConstraintSatisfied(final long nowElapsed, boolean state) { + if (setConstraintSatisfied(CONSTRAINT_WITHIN_QUOTA, nowElapsed, state)) { // The constraint was changed. Update the ready flag. mReadyWithinQuota = state; return true; @@ -1166,8 +1173,8 @@ public final class JobStatus { } /** @return true if the constraint was changed, false otherwise. */ - boolean setExpeditedJobQuotaConstraintSatisfied(boolean state) { - if (setConstraintSatisfied(CONSTRAINT_WITHIN_EXPEDITED_QUOTA, state)) { + boolean setExpeditedJobQuotaConstraintSatisfied(final long nowElapsed, boolean state) { + if (setConstraintSatisfied(CONSTRAINT_WITHIN_EXPEDITED_QUOTA, nowElapsed, state)) { // The constraint was changed. Update the ready flag. mReadyWithinExpeditedQuota = state; // DeviceIdleJobsController currently only tracks jobs with the WILL_BE_FOREGROUND flag. @@ -1190,7 +1197,7 @@ public final class JobStatus { } /** @return true if the constraint was changed, false otherwise. */ - boolean setConstraintSatisfied(int constraint, boolean state) { + boolean setConstraintSatisfied(int constraint, final long nowElapsed, boolean state) { boolean old = (satisfiedConstraints&constraint) != 0; if (old == state) { return false; @@ -1212,6 +1219,12 @@ public final class JobStatus { : FrameworkStatsLog .SCHEDULED_JOB_CONSTRAINT_CHANGED__STATE__UNSATISFIED); } + + mConstraintUpdatedTimesElapsed[mConstraintChangeHistoryIndex] = nowElapsed; + mConstraintStatusHistory[mConstraintChangeHistoryIndex] = satisfiedConstraints; + mConstraintChangeHistoryIndex = + (mConstraintChangeHistoryIndex + 1) % NUM_CONSTRAINT_CHANGE_HISTORY; + return true; } @@ -1700,7 +1713,7 @@ public final class JobStatus { } // Dumpsys infrastructure - public void dump(IndentingPrintWriter pw, boolean full, long elapsedRealtimeMillis) { + public void dump(IndentingPrintWriter pw, boolean full, long nowElapsed) { UserHandle.formatUid(pw, callingUid); pw.print(" tag="); pw.println(tag); @@ -1830,6 +1843,22 @@ public final class JobStatus { dumpConstraints(pw, ((requiredConstraints | CONSTRAINT_WITHIN_QUOTA) & ~satisfiedConstraints)); pw.println(); + + pw.println("Constraint history:"); + pw.increaseIndent(); + for (int h = 0; h < NUM_CONSTRAINT_CHANGE_HISTORY; ++h) { + final int idx = (h + mConstraintChangeHistoryIndex) % NUM_CONSTRAINT_CHANGE_HISTORY; + if (mConstraintUpdatedTimesElapsed[idx] == 0) { + continue; + } + TimeUtils.formatDuration(mConstraintUpdatedTimesElapsed[idx], nowElapsed, pw); + // dumpConstraints prepends with a space, so no need to add a space after the = + pw.print(" ="); + dumpConstraints(pw, mConstraintStatusHistory[idx]); + pw.println(); + } + pw.decreaseIndent(); + if (dozeWhitelisted) { pw.println("Doze whitelisted: true"); } @@ -1910,26 +1939,25 @@ public final class JobStatus { pw.increaseIndent(); if (whenStandbyDeferred != 0) { pw.print("Deferred since: "); - TimeUtils.formatDuration(whenStandbyDeferred, elapsedRealtimeMillis, pw); + TimeUtils.formatDuration(whenStandbyDeferred, nowElapsed, pw); pw.println(); } if (mFirstForceBatchedTimeElapsed != 0) { pw.print("Time since first force batch attempt: "); - TimeUtils.formatDuration(mFirstForceBatchedTimeElapsed, elapsedRealtimeMillis, pw); + TimeUtils.formatDuration(mFirstForceBatchedTimeElapsed, nowElapsed, pw); pw.println(); } pw.decreaseIndent(); pw.print("Enqueue time: "); - TimeUtils.formatDuration(enqueueTime, elapsedRealtimeMillis, pw); + TimeUtils.formatDuration(enqueueTime, nowElapsed, pw); pw.println(); pw.print("Run time: earliest="); - formatRunTime(pw, earliestRunTimeElapsedMillis, NO_EARLIEST_RUNTIME, elapsedRealtimeMillis); + formatRunTime(pw, earliestRunTimeElapsedMillis, NO_EARLIEST_RUNTIME, nowElapsed); pw.print(", latest="); - formatRunTime(pw, latestRunTimeElapsedMillis, NO_LATEST_RUNTIME, elapsedRealtimeMillis); + formatRunTime(pw, latestRunTimeElapsedMillis, NO_LATEST_RUNTIME, nowElapsed); pw.print(", original latest="); - formatRunTime(pw, mOriginalLatestRunTimeElapsedMillis, - NO_LATEST_RUNTIME, elapsedRealtimeMillis); + formatRunTime(pw, mOriginalLatestRunTimeElapsedMillis, NO_LATEST_RUNTIME, nowElapsed); pw.println(); if (numFailures != 0) { pw.print("Num failures: "); pw.println(numFailures); diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java index 2196b16e0846a..824fa7fc1659e 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java @@ -626,6 +626,7 @@ public final class QuotaController extends StateController { @Override public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) { + final long nowElapsed = sElapsedRealtimeClock.millis(); final int userId = jobStatus.getSourceUserId(); final String pkgName = jobStatus.getSourcePackageName(); ArraySet jobs = mTrackedJobs.get(userId, pkgName); @@ -636,11 +637,11 @@ public final class QuotaController extends StateController { jobs.add(jobStatus); jobStatus.setTrackingController(JobStatus.TRACKING_QUOTA); final boolean isWithinQuota = isWithinQuotaLocked(jobStatus); - setConstraintSatisfied(jobStatus, isWithinQuota); + setConstraintSatisfied(jobStatus, nowElapsed, isWithinQuota); final boolean outOfEJQuota; if (jobStatus.isRequestedExpeditedJob()) { final boolean isWithinEJQuota = isWithinEJQuotaLocked(jobStatus); - setExpeditedConstraintSatisfied(jobStatus, isWithinEJQuota); + setExpeditedConstraintSatisfied(jobStatus, nowElapsed, isWithinEJQuota); outOfEJQuota = !isWithinEJQuota; } else { outOfEJQuota = false; @@ -1397,7 +1398,8 @@ public final class QuotaController extends StateController { synchronized (mLock) { final ShrinkableDebits quota = getEJQuotaLocked(userId, packageName); quota.transactOnDebitsLocked(-credit); - if (maybeUpdateConstraintForPkgLocked(userId, packageName)) { + if (maybeUpdateConstraintForPkgLocked(sElapsedRealtimeClock.millis(), + userId, packageName)) { mStateChangedListener.onControllerStateChanged(); } } @@ -1499,11 +1501,12 @@ public final class QuotaController extends StateController { private void maybeUpdateAllConstraintsLocked() { boolean changed = false; + final long nowElapsed = sElapsedRealtimeClock.millis(); for (int u = 0; u < mTrackedJobs.numMaps(); ++u) { final int userId = mTrackedJobs.keyAt(u); for (int p = 0; p < mTrackedJobs.numElementsForKey(userId); ++p) { final String packageName = mTrackedJobs.keyAt(u, p); - changed |= maybeUpdateConstraintForPkgLocked(userId, packageName); + changed |= maybeUpdateConstraintForPkgLocked(nowElapsed, userId, packageName); } } if (changed) { @@ -1516,7 +1519,7 @@ public final class QuotaController extends StateController { * * @return true if at least one job had its bit changed */ - private boolean maybeUpdateConstraintForPkgLocked(final int userId, + private boolean maybeUpdateConstraintForPkgLocked(final long nowElapsed, final int userId, @NonNull final String packageName) { ArraySet jobs = mTrackedJobs.get(userId, packageName); if (jobs == null || jobs.size() == 0) { @@ -1533,21 +1536,21 @@ public final class QuotaController extends StateController { if (isTopStartedJobLocked(js)) { // Job was started while the app was in the TOP state so we should allow it to // finish. - changed |= js.setQuotaConstraintSatisfied(true); + changed |= js.setQuotaConstraintSatisfied(nowElapsed, true); } else if (realStandbyBucket != ACTIVE_INDEX && realStandbyBucket == js.getEffectiveStandbyBucket()) { // An app in the ACTIVE bucket may be out of quota while the job could be in quota // for some reason. Therefore, avoid setting the real value here and check each job // individually. - changed |= setConstraintSatisfied(js, realInQuota); + changed |= setConstraintSatisfied(js, nowElapsed, realInQuota); } else { // This job is somehow exempted. Need to determine its own quota status. - changed |= setConstraintSatisfied(js, isWithinQuotaLocked(js)); + changed |= setConstraintSatisfied(js, nowElapsed, isWithinQuotaLocked(js)); } if (js.isRequestedExpeditedJob()) { boolean isWithinEJQuota = isWithinEJQuotaLocked(js); - changed |= setExpeditedConstraintSatisfied(js, isWithinEJQuota); + changed |= setExpeditedConstraintSatisfied(js, nowElapsed, isWithinEJQuota); outOfEJQuota |= !isWithinEJQuota; } } @@ -1566,14 +1569,21 @@ public final class QuotaController extends StateController { private final SparseArrayMap mToScheduleStartAlarms = new SparseArrayMap<>(); public boolean wasJobChanged; + long mUpdateTimeElapsed = 0; + + void prepare() { + mUpdateTimeElapsed = sElapsedRealtimeClock.millis(); + } @Override public void accept(JobStatus jobStatus) { - wasJobChanged |= setConstraintSatisfied(jobStatus, isWithinQuotaLocked(jobStatus)); + wasJobChanged |= setConstraintSatisfied( + jobStatus, mUpdateTimeElapsed, isWithinQuotaLocked(jobStatus)); final boolean outOfEJQuota; if (jobStatus.isRequestedExpeditedJob()) { final boolean isWithinEJQuota = isWithinEJQuotaLocked(jobStatus); - wasJobChanged |= setExpeditedConstraintSatisfied(jobStatus, isWithinEJQuota); + wasJobChanged |= setExpeditedConstraintSatisfied( + jobStatus, mUpdateTimeElapsed, isWithinEJQuota); outOfEJQuota = !isWithinEJQuota; } else { outOfEJQuota = false; @@ -1611,6 +1621,7 @@ public final class QuotaController extends StateController { private final UidConstraintUpdater mUpdateUidConstraints = new UidConstraintUpdater(); private boolean maybeUpdateConstraintForUidLocked(final int uid) { + mUpdateUidConstraints.prepare(); mService.getJobStore().forEachJobForSourceUid(uid, mUpdateUidConstraints); mUpdateUidConstraints.postProcess(); @@ -1716,21 +1727,22 @@ public final class QuotaController extends StateController { mInQuotaAlarmListener.addAlarmLocked(userId, packageName, inQuotaTimeElapsed); } - private boolean setConstraintSatisfied(@NonNull JobStatus jobStatus, boolean isWithinQuota) { + private boolean setConstraintSatisfied(@NonNull JobStatus jobStatus, long nowElapsed, + boolean isWithinQuota) { if (!isWithinQuota && jobStatus.getWhenStandbyDeferred() == 0) { // Mark that the job is being deferred due to buckets. - jobStatus.setWhenStandbyDeferred(sElapsedRealtimeClock.millis()); + jobStatus.setWhenStandbyDeferred(nowElapsed); } - return jobStatus.setQuotaConstraintSatisfied(isWithinQuota); + return jobStatus.setQuotaConstraintSatisfied(nowElapsed, isWithinQuota); } /** * If the satisfaction changes, this will tell connectivity & background jobs controller to * also re-evaluate their state. */ - private boolean setExpeditedConstraintSatisfied(@NonNull JobStatus jobStatus, + private boolean setExpeditedConstraintSatisfied(@NonNull JobStatus jobStatus, long nowElapsed, boolean isWithinQuota) { - if (jobStatus.setExpeditedJobQuotaConstraintSatisfied(isWithinQuota)) { + if (jobStatus.setExpeditedJobQuotaConstraintSatisfied(nowElapsed, isWithinQuota)) { mBackgroundJobsController.evaluateStateLocked(jobStatus); mConnectivityController.evaluateStateLocked(jobStatus); if (isWithinQuota && jobStatus.isReady()) { @@ -2188,7 +2200,8 @@ public final class QuotaController extends StateController { final ShrinkableDebits quota = getEJQuotaLocked(mPkg.userId, mPkg.packageName); quota.transactOnDebitsLocked(-mEJRewardTopAppMs * numTimeChunks); - if (maybeUpdateConstraintForPkgLocked(mPkg.userId, mPkg.packageName)) { + if (maybeUpdateConstraintForPkgLocked(nowElapsed, + mPkg.userId, mPkg.packageName)) { mStateChangedListener.onControllerStateChanged(); } } @@ -2292,7 +2305,8 @@ public final class QuotaController extends StateController { if (timer != null && timer.isActive()) { timer.rescheduleCutoff(); } - if (maybeUpdateConstraintForPkgLocked(userId, packageName)) { + if (maybeUpdateConstraintForPkgLocked(sElapsedRealtimeClock.millis(), + userId, packageName)) { mStateChangedListener.onControllerStateChanged(); } } @@ -2417,7 +2431,8 @@ public final class QuotaController extends StateController { if (timeRemainingMs <= 50) { // Less than 50 milliseconds left. Start process of shutting down jobs. if (DEBUG) Slog.d(TAG, pkg + " has reached its quota."); - if (maybeUpdateConstraintForPkgLocked(pkg.userId, pkg.packageName)) { + if (maybeUpdateConstraintForPkgLocked(sElapsedRealtimeClock.millis(), + pkg.userId, pkg.packageName)) { mStateChangedListener.onControllerStateChanged(); } } else { @@ -2444,7 +2459,8 @@ public final class QuotaController extends StateController { pkg.userId, pkg.packageName); if (timeRemainingMs <= 0) { if (DEBUG) Slog.d(TAG, pkg + " has reached its EJ quota."); - if (maybeUpdateConstraintForPkgLocked(pkg.userId, pkg.packageName)) { + if (maybeUpdateConstraintForPkgLocked(sElapsedRealtimeClock.millis(), + pkg.userId, pkg.packageName)) { mStateChangedListener.onControllerStateChanged(); } } else { @@ -2475,7 +2491,8 @@ public final class QuotaController extends StateController { if (DEBUG) { Slog.d(TAG, "Checking pkg " + string(userId, packageName)); } - if (maybeUpdateConstraintForPkgLocked(userId, packageName)) { + if (maybeUpdateConstraintForPkgLocked(sElapsedRealtimeClock.millis(), + userId, packageName)) { mStateChangedListener.onControllerStateChanged(); } break; diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/StorageController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/StorageController.java index 0731918d83a1d..8678913639129 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/StorageController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/StorageController.java @@ -61,9 +61,11 @@ public final class StorageController extends StateController { @Override public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) { if (taskStatus.hasStorageNotLowConstraint()) { + final long nowElapsed = sElapsedRealtimeClock.millis(); mTrackedTasks.add(taskStatus); taskStatus.setTrackingController(JobStatus.TRACKING_STORAGE); - taskStatus.setStorageNotLowConstraintSatisfied(mStorageTracker.isStorageNotLow()); + taskStatus.setStorageNotLowConstraintSatisfied( + nowElapsed, mStorageTracker.isStorageNotLow()); } } @@ -76,12 +78,13 @@ public final class StorageController extends StateController { } private void maybeReportNewStorageState() { + final long nowElapsed = sElapsedRealtimeClock.millis(); final boolean storageNotLow = mStorageTracker.isStorageNotLow(); boolean reportChange = false; synchronized (mLock) { for (int i = mTrackedTasks.size() - 1; i >= 0; i--) { final JobStatus ts = mTrackedTasks.valueAt(i); - reportChange |= ts.setStorageNotLowConstraintSatisfied(storageNotLow); + reportChange |= ts.setStorageNotLowConstraintSatisfied(nowElapsed, storageNotLow); } } if (storageNotLow) { diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java index ede14ec06c71d..e8ebfb53fde8a 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/TimeController.java @@ -258,9 +258,9 @@ public final class TimeController extends StateController { if (jobDeadline <= nowElapsedMillis) { if (job.hasTimingDelayConstraint()) { - job.setTimingDelayConstraintSatisfied(true); + job.setTimingDelayConstraintSatisfied(nowElapsedMillis, true); } - job.setDeadlineConstraintSatisfied(true); + job.setDeadlineConstraintSatisfied(nowElapsedMillis, true); return true; } return false; @@ -332,7 +332,7 @@ public final class TimeController extends StateController { private boolean evaluateTimingDelayConstraint(JobStatus job, long nowElapsedMillis) { final long jobDelayTime = job.getEarliestRunTime(); if (jobDelayTime <= nowElapsedMillis) { - job.setTimingDelayConstraintSatisfied(true); + job.setTimingDelayConstraintSatisfied(nowElapsedMillis, true); return true; } return false; diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java index 6d40034c60003..91b3cb7dbdd9f 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java @@ -25,6 +25,7 @@ import static com.android.server.job.JobSchedulerService.NEVER_INDEX; import static com.android.server.job.JobSchedulerService.RARE_INDEX; import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX; import static com.android.server.job.JobSchedulerService.WORKING_INDEX; +import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import static com.android.server.job.controllers.JobStatus.CONSTRAINT_BACKGROUND_NOT_RESTRICTED; import static com.android.server.job.controllers.JobStatus.CONSTRAINT_BATTERY_NOT_LOW; import static com.android.server.job.controllers.JobStatus.CONSTRAINT_CHARGING; @@ -101,7 +102,7 @@ public class JobStatusTest { Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC); JobSchedulerService.sUptimeMillisClock = Clock.fixed(SystemClock.uptimeClock().instant(), ZoneOffset.UTC); - JobSchedulerService.sElapsedRealtimeClock = + sElapsedRealtimeClock = Clock.fixed(SystemClock.elapsedRealtimeClock().instant(), ZoneOffset.UTC); } @@ -204,7 +205,7 @@ public class JobStatusTest { @Test public void testFraction() throws Exception { - final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); + final long now = sElapsedRealtimeClock.millis(); assertEquals(1, createJobStatus(0, Long.MAX_VALUE).getFractionRunTime(), DELTA); @@ -261,15 +262,15 @@ public class JobStatusTest { final JobStatus job = createJobStatus(jobInfo); markImplicitConstraintsSatisfied(job, true); - job.setChargingConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); - job.setChargingConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); markImplicitConstraintsSatisfied(job, false); - job.setChargingConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); - job.setChargingConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); } @@ -282,15 +283,15 @@ public class JobStatusTest { final JobStatus job = createJobStatus(jobInfo); markImplicitConstraintsSatisfied(job, true); - job.setIdleConstraintSatisfied(false); + job.setIdleConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_IDLE)); - job.setIdleConstraintSatisfied(true); + job.setIdleConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_IDLE)); markImplicitConstraintsSatisfied(job, false); - job.setIdleConstraintSatisfied(false); + job.setIdleConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_IDLE)); - job.setIdleConstraintSatisfied(true); + job.setIdleConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_IDLE)); } @@ -303,15 +304,15 @@ public class JobStatusTest { final JobStatus job = createJobStatus(jobInfo); markImplicitConstraintsSatisfied(job, true); - job.setBatteryNotLowConstraintSatisfied(false); + job.setBatteryNotLowConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_BATTERY_NOT_LOW)); - job.setBatteryNotLowConstraintSatisfied(true); + job.setBatteryNotLowConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_BATTERY_NOT_LOW)); markImplicitConstraintsSatisfied(job, false); - job.setBatteryNotLowConstraintSatisfied(false); + job.setBatteryNotLowConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_BATTERY_NOT_LOW)); - job.setBatteryNotLowConstraintSatisfied(true); + job.setBatteryNotLowConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_BATTERY_NOT_LOW)); } @@ -324,15 +325,15 @@ public class JobStatusTest { final JobStatus job = createJobStatus(jobInfo); markImplicitConstraintsSatisfied(job, true); - job.setStorageNotLowConstraintSatisfied(false); + job.setStorageNotLowConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_STORAGE_NOT_LOW)); - job.setStorageNotLowConstraintSatisfied(true); + job.setStorageNotLowConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_STORAGE_NOT_LOW)); markImplicitConstraintsSatisfied(job, false); - job.setStorageNotLowConstraintSatisfied(false); + job.setStorageNotLowConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_STORAGE_NOT_LOW)); - job.setStorageNotLowConstraintSatisfied(true); + job.setStorageNotLowConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_STORAGE_NOT_LOW)); } @@ -345,15 +346,15 @@ public class JobStatusTest { final JobStatus job = createJobStatus(jobInfo); markImplicitConstraintsSatisfied(job, true); - job.setTimingDelayConstraintSatisfied(false); + job.setTimingDelayConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_TIMING_DELAY)); - job.setTimingDelayConstraintSatisfied(true); + job.setTimingDelayConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_TIMING_DELAY)); markImplicitConstraintsSatisfied(job, false); - job.setTimingDelayConstraintSatisfied(false); + job.setTimingDelayConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_TIMING_DELAY)); - job.setTimingDelayConstraintSatisfied(true); + job.setTimingDelayConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_TIMING_DELAY)); } @@ -366,15 +367,15 @@ public class JobStatusTest { final JobStatus job = createJobStatus(jobInfo); markImplicitConstraintsSatisfied(job, true); - job.setDeadlineConstraintSatisfied(false); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE)); - job.setDeadlineConstraintSatisfied(true); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE)); markImplicitConstraintsSatisfied(job, false); - job.setDeadlineConstraintSatisfied(false); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE)); - job.setDeadlineConstraintSatisfied(true); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE)); } @@ -387,15 +388,15 @@ public class JobStatusTest { final JobStatus job = createJobStatus(jobInfo); markImplicitConstraintsSatisfied(job, true); - job.setConnectivityConstraintSatisfied(false); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); - job.setConnectivityConstraintSatisfied(true); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); markImplicitConstraintsSatisfied(job, false); - job.setConnectivityConstraintSatisfied(false); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); - job.setConnectivityConstraintSatisfied(true); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); } @@ -410,15 +411,15 @@ public class JobStatusTest { final JobStatus job = createJobStatus(jobInfo); markImplicitConstraintsSatisfied(job, true); - job.setContentTriggerConstraintSatisfied(false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); - job.setContentTriggerConstraintSatisfied(true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); markImplicitConstraintsSatisfied(job, false); - job.setContentTriggerConstraintSatisfied(false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); - job.setContentTriggerConstraintSatisfied(true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); } @@ -436,15 +437,15 @@ public class JobStatusTest { markImplicitConstraintsSatisfied(job, false); - job.setChargingConstraintSatisfied(false); - job.setConnectivityConstraintSatisfied(false); - job.setContentTriggerConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); - job.setChargingConstraintSatisfied(true); - job.setConnectivityConstraintSatisfied(true); - job.setContentTriggerConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); // Still false because implicit constraints aren't satisfied. assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); @@ -452,61 +453,61 @@ public class JobStatusTest { markImplicitConstraintsSatisfied(job, true); - job.setChargingConstraintSatisfied(false); - job.setConnectivityConstraintSatisfied(false); - job.setContentTriggerConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); // Turn on constraints one at a time. - job.setChargingConstraintSatisfied(true); - job.setConnectivityConstraintSatisfied(false); - job.setContentTriggerConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); - job.setChargingConstraintSatisfied(false); - job.setConnectivityConstraintSatisfied(false); - job.setContentTriggerConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); - job.setChargingConstraintSatisfied(false); - job.setConnectivityConstraintSatisfied(true); - job.setContentTriggerConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); // With two of the 3 constraints satisfied (and implicit constraints also satisfied), only // the unsatisfied constraint should return true. - job.setChargingConstraintSatisfied(true); - job.setConnectivityConstraintSatisfied(false); - job.setContentTriggerConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); - job.setChargingConstraintSatisfied(true); - job.setConnectivityConstraintSatisfied(true); - job.setContentTriggerConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); - job.setChargingConstraintSatisfied(false); - job.setConnectivityConstraintSatisfied(true); - job.setContentTriggerConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); - job.setChargingConstraintSatisfied(true); - job.setConnectivityConstraintSatisfied(true); - job.setContentTriggerConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setConnectivityConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONNECTIVITY)); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); @@ -526,15 +527,15 @@ public class JobStatusTest { markImplicitConstraintsSatisfied(job, false); - job.setChargingConstraintSatisfied(false); - job.setContentTriggerConstraintSatisfied(false); - job.setDeadlineConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE)); - job.setChargingConstraintSatisfied(true); - job.setContentTriggerConstraintSatisfied(true); - job.setDeadlineConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), true); // Still false because implicit constraints aren't satisfied. assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); @@ -542,18 +543,18 @@ public class JobStatusTest { markImplicitConstraintsSatisfied(job, true); - job.setChargingConstraintSatisfied(false); - job.setContentTriggerConstraintSatisfied(false); - job.setDeadlineConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); // Once implicit constraint are satisfied, deadline constraint should always return true. assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE)); // Turn on constraints one at a time. - job.setChargingConstraintSatisfied(true); - job.setContentTriggerConstraintSatisfied(false); - job.setDeadlineConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); // Deadline should force isReady to be true, but isn't needed for the job to be // considered ready. @@ -561,17 +562,17 @@ public class JobStatusTest { // Once implicit constraint are satisfied, deadline constraint should always return true. assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE)); - job.setChargingConstraintSatisfied(false); - job.setContentTriggerConstraintSatisfied(true); - job.setDeadlineConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); // Once implicit constraint are satisfied, deadline constraint should always return true. assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE)); - job.setChargingConstraintSatisfied(false); - job.setContentTriggerConstraintSatisfied(false); - job.setDeadlineConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), true); // Since the deadline constraint is satisfied, none of the other explicit constraints are // needed. assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); @@ -581,33 +582,33 @@ public class JobStatusTest { // With two of the 3 constraints satisfied (and implicit constraints also satisfied), only // the unsatisfied constraint should return true. - job.setChargingConstraintSatisfied(true); - job.setContentTriggerConstraintSatisfied(true); - job.setDeadlineConstraintSatisfied(false); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); // Once implicit constraint are satisfied, deadline constraint should always return true. assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE)); - job.setChargingConstraintSatisfied(true); - job.setContentTriggerConstraintSatisfied(false); - job.setDeadlineConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); // Once implicit constraint are satisfied, deadline constraint should always return true. assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE)); - job.setChargingConstraintSatisfied(false); - job.setContentTriggerConstraintSatisfied(true); - job.setDeadlineConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), false); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); // Once implicit constraint are satisfied, deadline constraint should always return true. assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEADLINE)); - job.setChargingConstraintSatisfied(true); - job.setContentTriggerConstraintSatisfied(true); - job.setDeadlineConstraintSatisfied(true); + job.setChargingConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setContentTriggerConstraintSatisfied(sElapsedRealtimeClock.millis(), true); + job.setDeadlineConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CHARGING)); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_CONTENT_TRIGGER)); // Once implicit constraint are satisfied, deadline constraint should always return true. @@ -621,15 +622,15 @@ public class JobStatusTest { new JobInfo.Builder(101, new ComponentName("foo", "bar")).build()); markImplicitConstraintsSatisfied(job, false); - job.setDeviceNotDozingConstraintSatisfied(false, false); + job.setDeviceNotDozingConstraintSatisfied(sElapsedRealtimeClock.millis(), false, false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_DEVICE_NOT_DOZING)); - job.setDeviceNotDozingConstraintSatisfied(true, false); + job.setDeviceNotDozingConstraintSatisfied(sElapsedRealtimeClock.millis(), true, false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_DEVICE_NOT_DOZING)); markImplicitConstraintsSatisfied(job, true); - job.setDeviceNotDozingConstraintSatisfied(false, false); + job.setDeviceNotDozingConstraintSatisfied(sElapsedRealtimeClock.millis(), false, false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEVICE_NOT_DOZING)); - job.setDeviceNotDozingConstraintSatisfied(true, false); + job.setDeviceNotDozingConstraintSatisfied(sElapsedRealtimeClock.millis(), true, false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_DEVICE_NOT_DOZING)); } @@ -640,15 +641,15 @@ public class JobStatusTest { new JobInfo.Builder(101, new ComponentName("foo", "bar")).build()); markImplicitConstraintsSatisfied(job, false); - job.setQuotaConstraintSatisfied(false); + job.setQuotaConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_WITHIN_QUOTA)); - job.setQuotaConstraintSatisfied(true); + job.setQuotaConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_WITHIN_QUOTA)); markImplicitConstraintsSatisfied(job, true); - job.setQuotaConstraintSatisfied(false); + job.setQuotaConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_WITHIN_QUOTA)); - job.setQuotaConstraintSatisfied(true); + job.setQuotaConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_WITHIN_QUOTA)); } @@ -659,22 +660,24 @@ public class JobStatusTest { new JobInfo.Builder(101, new ComponentName("foo", "bar")).build()); markImplicitConstraintsSatisfied(job, false); - job.setBackgroundNotRestrictedConstraintSatisfied(false); + job.setBackgroundNotRestrictedConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_BACKGROUND_NOT_RESTRICTED)); - job.setBackgroundNotRestrictedConstraintSatisfied(true); + job.setBackgroundNotRestrictedConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertFalse(job.wouldBeReadyWithConstraint(CONSTRAINT_BACKGROUND_NOT_RESTRICTED)); markImplicitConstraintsSatisfied(job, true); - job.setBackgroundNotRestrictedConstraintSatisfied(false); + job.setBackgroundNotRestrictedConstraintSatisfied(sElapsedRealtimeClock.millis(), false); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_BACKGROUND_NOT_RESTRICTED)); - job.setBackgroundNotRestrictedConstraintSatisfied(true); + job.setBackgroundNotRestrictedConstraintSatisfied(sElapsedRealtimeClock.millis(), true); assertTrue(job.wouldBeReadyWithConstraint(CONSTRAINT_BACKGROUND_NOT_RESTRICTED)); } private void markImplicitConstraintsSatisfied(JobStatus job, boolean isSatisfied) { - job.setQuotaConstraintSatisfied(isSatisfied); - job.setDeviceNotDozingConstraintSatisfied(isSatisfied, false); - job.setBackgroundNotRestrictedConstraintSatisfied(isSatisfied); + job.setQuotaConstraintSatisfied(sElapsedRealtimeClock.millis(), isSatisfied); + job.setDeviceNotDozingConstraintSatisfied( + sElapsedRealtimeClock.millis(), isSatisfied, false); + job.setBackgroundNotRestrictedConstraintSatisfied( + sElapsedRealtimeClock.millis(), isSatisfied); } private static JobStatus createJobStatus(long earliestRunTimeElapsedMillis, diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java index b72121f096ba0..88a691bbc2097 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java @@ -359,8 +359,9 @@ public class QuotaControllerTest { // Make sure tests aren't passing just because the default bucket is likely ACTIVE. js.setStandbyBucket(FREQUENT_INDEX); // Make sure Doze and background-not-restricted don't affect tests. - js.setDeviceNotDozingConstraintSatisfied(/* state */ true, /* allowlisted */false); - js.setBackgroundNotRestrictedConstraintSatisfied(true); + js.setDeviceNotDozingConstraintSatisfied(/* nowElapsed */ sElapsedRealtimeClock.millis(), + /* state */ true, /* allowlisted */false); + js.setBackgroundNotRestrictedConstraintSatisfied(sElapsedRealtimeClock.millis(), true); return js; }