diff options
2 files changed, 76 insertions, 594 deletions
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 2b0a833e1d1f..ee0f9e8f9658 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 @@ -37,7 +37,6 @@ import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.AlarmManager; import android.app.IUidObserver; -import android.app.job.JobInfo; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal.UsageEventListener; @@ -166,28 +165,6 @@ public final class QuotaController extends StateController { public long inQuotaTimeElapsed; /** - * The time after which the app will be under the bucket quota and can start running - * low priority jobs again. This is only valid if - * {@link #executionTimeInWindowMs} >= - * {@link #mAllowedTimePerPeriodMs} * (1 - {@link #mAllowedTimeSurplusPriorityLow}), - * {@link #executionTimeInMaxPeriodMs} >= {@link #mMaxExecutionTimeMs}, - * {@link #bgJobCountInWindow} >= {@link #jobCountLimit}, or - * {@link #sessionCountInWindow} >= {@link #sessionCountLimit}. - */ - public long inQuotaTimeLowElapsed; - - /** - * The time after which the app will be under the bucket quota and can start running - * min priority jobs again. This is only valid if - * {@link #executionTimeInWindowMs} >= - * {@link #mAllowedTimePerPeriodMs} * (1 - {@link #mAllowedTimeSurplusPriorityMin}), - * {@link #executionTimeInMaxPeriodMs} >= {@link #mMaxExecutionTimeMs}, - * {@link #bgJobCountInWindow} >= {@link #jobCountLimit}, or - * {@link #sessionCountInWindow} >= {@link #sessionCountLimit}. - */ - public long inQuotaTimeMinElapsed; - - /** * The time after which {@link #jobCountInRateLimitingWindow} should be considered invalid, * in the elapsed realtime timebase. */ @@ -227,8 +204,6 @@ public final class QuotaController extends StateController { + "bgJobCountInMaxPeriod=" + bgJobCountInMaxPeriod + ", " + "sessionCountInWindow=" + sessionCountInWindow + ", " + "inQuotaTime=" + inQuotaTimeElapsed + ", " - + "inQuotaTimeLow=" + inQuotaTimeLowElapsed + ", " - + "inQuotaTimeMin=" + inQuotaTimeMinElapsed + ", " + "rateLimitJobCountExpirationTime=" + jobRateLimitExpirationTimeElapsed + ", " + "rateLimitJobCountWindow=" + jobCountInRateLimitingWindow + ", " + "rateLimitSessionCountExpirationTime=" @@ -385,24 +360,6 @@ public final class QuotaController extends StateController { */ private long mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs; - /** - * The percentage of {@link #mAllowedTimePerPeriodMs} that should not be used by - * {@link JobInfo#PRIORITY_LOW low priority} jobs. In other words, there must be a minimum - * surplus of this amount of remaining allowed time before we start running low priority - * jobs. - */ - private float mAllowedTimeSurplusPriorityLow = - QcConstants.DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_LOW; - - /** - * The percentage of {@link #mAllowedTimePerPeriodMs} that should not be used by - * {@link JobInfo#PRIORITY_MIN min priority} jobs. In other words, there must be a minimum - * surplus of this amount of remaining allowed time before we start running low priority - * jobs. - */ - private float mAllowedTimeSurplusPriorityMin = - QcConstants.DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_MIN; - /** The period of time used to rate limit recently run jobs. */ private long mRateLimitingWindowMs = QcConstants.DEFAULT_RATE_LIMITING_WINDOW_MS; @@ -828,8 +785,7 @@ public final class QuotaController extends StateController { return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS; } return getTimeUntilQuotaConsumedLocked( - jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(), - jobStatus.getEffectivePriority()); + jobStatus.getSourceUserId(), jobStatus.getSourcePackageName()); } // Expedited job. @@ -919,8 +875,7 @@ public final class QuotaController extends StateController { return isTopStartedJobLocked(jobStatus) || isUidInForeground(jobStatus.getSourceUid()) || isWithinQuotaLocked( - jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(), standbyBucket, - jobStatus.getEffectivePriority()); + jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(), standbyBucket); } @GuardedBy("mLock") @@ -937,7 +892,7 @@ public final class QuotaController extends StateController { @VisibleForTesting @GuardedBy("mLock") boolean isWithinQuotaLocked(final int userId, @NonNull final String packageName, - final int standbyBucket, final int priority) { + final int standbyBucket) { if (!mIsEnabled) { return true; } @@ -945,18 +900,9 @@ public final class QuotaController extends StateController { if (isQuotaFreeLocked(standbyBucket)) return true; - final long minSurplus; - if (priority <= JobInfo.PRIORITY_MIN) { - minSurplus = (long) - (mAllowedTimePerPeriodMs[standbyBucket] * mAllowedTimeSurplusPriorityMin); - } else if (priority <= JobInfo.PRIORITY_LOW) { - minSurplus = (long) - (mAllowedTimePerPeriodMs[standbyBucket] * mAllowedTimeSurplusPriorityLow); - } else { - minSurplus = 0; - } ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket); - return getRemainingExecutionTimeLocked(stats) > minSurplus + // TODO: use a higher minimum remaining time for jobs with MINIMUM priority + return getRemainingExecutionTimeLocked(stats) > 0 && isUnderJobCountQuotaLocked(stats, standbyBucket) && isUnderSessionCountQuotaLocked(stats, standbyBucket); } @@ -1074,8 +1020,7 @@ public final class QuotaController extends StateController { * job is running. */ @VisibleForTesting - long getTimeUntilQuotaConsumedLocked(final int userId, @NonNull final String packageName, - @JobInfo.Priority int jobPriority) { + long getTimeUntilQuotaConsumedLocked(final int userId, @NonNull final String packageName) { final long nowElapsed = sElapsedRealtimeClock.millis(); final int standbyBucket = JobSchedulerService.standbyBucketForPackage( packageName, userId, nowElapsed); @@ -1096,15 +1041,11 @@ public final class QuotaController extends StateController { final long startWindowElapsed = nowElapsed - stats.windowSizeMs; final long startMaxElapsed = nowElapsed - MAX_PERIOD_MS; - final long allowedTimePerPeriodMs = getAllowedTimePerPeriodMs(standbyBucket, jobPriority); + final long allowedTimePerPeriodMs = mAllowedTimePerPeriodMs[standbyBucket]; final long allowedTimeRemainingMs = allowedTimePerPeriodMs - stats.executionTimeInWindowMs; final long maxExecutionTimeRemainingMs = mMaxExecutionTimeMs - stats.executionTimeInMaxPeriodMs; - if (maxExecutionTimeRemainingMs < 0) { - return 0; - } - // Regular ACTIVE case. Since the bucket size equals the allowed time, the app jobs can // essentially run until they reach the maximum limit. if (stats.windowSizeMs == mAllowedTimePerPeriodMs[standbyBucket]) { @@ -1112,10 +1053,6 @@ public final class QuotaController extends StateController { sessions, startMaxElapsed, maxExecutionTimeRemainingMs); } - if (allowedTimeRemainingMs < 0) { - return 0; - } - // Need to check both max time and period time in case one is less than the other. // For example, max time remaining could be less than bucket time remaining, but sessions // contributing to the max time remaining could phase out enough that we'd want to use the @@ -1127,21 +1064,6 @@ public final class QuotaController extends StateController { sessions, startWindowElapsed, allowedTimeRemainingMs)); } - private long getAllowedTimePerPeriodMs(int standbyBucket, @JobInfo.Priority int jobPriority) { - return getAllowedTimePerPeriodMs(mAllowedTimePerPeriodMs[standbyBucket], jobPriority); - } - - private long getAllowedTimePerPeriodMs(long initialAllowedTime, - @JobInfo.Priority int jobPriority) { - if (jobPriority <= JobInfo.PRIORITY_MIN) { - return (long) (initialAllowedTime * (1 - mAllowedTimeSurplusPriorityMin)); - } - if (jobPriority <= JobInfo.PRIORITY_LOW) { - return (long) (initialAllowedTime * (1 - mAllowedTimeSurplusPriorityLow)); - } - return initialAllowedTime; - } - /** * Calculates how much time it will take, in milliseconds, until the quota is fully consumed. * @@ -1299,15 +1221,10 @@ public final class QuotaController extends StateController { stats.sessionCountInWindow = 0; if (stats.jobCountLimit == 0 || stats.sessionCountLimit == 0) { // App won't be in quota until configuration changes. - stats.inQuotaTimeElapsed = stats.inQuotaTimeLowElapsed = stats.inQuotaTimeMinElapsed = - Long.MAX_VALUE; + stats.inQuotaTimeElapsed = Long.MAX_VALUE; } else { stats.inQuotaTimeElapsed = 0; } - final long allowedTimeMinMs = - getAllowedTimePerPeriodMs(stats.allowedTimePerPeriodMs, JobInfo.PRIORITY_MIN); - final long allowedTimeLowMs = - getAllowedTimePerPeriodMs(stats.allowedTimePerPeriodMs, JobInfo.PRIORITY_LOW); final long allowedTimeIntoQuotaMs = stats.allowedTimePerPeriodMs - mQuotaBufferMs; Timer timer = mPkgTimers.get(userId, packageName); @@ -1326,25 +1243,13 @@ public final class QuotaController extends StateController { stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed, nowElapsed - allowedTimeIntoQuotaMs + stats.windowSizeMs); } - if (stats.executionTimeInWindowMs >= allowedTimeLowMs) { - stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed, - nowElapsed - allowedTimeLowMs + stats.windowSizeMs); - } - if (stats.executionTimeInWindowMs >= allowedTimeMinMs) { - stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed, - nowElapsed - allowedTimeMinMs + stats.windowSizeMs); - } if (stats.executionTimeInMaxPeriodMs >= mMaxExecutionTimeIntoQuotaMs) { final long inQuotaTime = nowElapsed - mMaxExecutionTimeIntoQuotaMs + MAX_PERIOD_MS; stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed, inQuotaTime); - stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed, inQuotaTime); - stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed, inQuotaTime); } if (stats.bgJobCountInWindow >= stats.jobCountLimit) { final long inQuotaTime = nowElapsed + stats.windowSizeMs; stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed, inQuotaTime); - stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed, inQuotaTime); - stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed, inQuotaTime); } } @@ -1386,23 +1291,9 @@ public final class QuotaController extends StateController { start + stats.executionTimeInWindowMs - allowedTimeIntoQuotaMs + stats.windowSizeMs); } - if (stats.executionTimeInWindowMs >= allowedTimeLowMs) { - stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed, - start + stats.executionTimeInWindowMs - allowedTimeLowMs - + stats.windowSizeMs); - } - if (stats.executionTimeInWindowMs >= allowedTimeMinMs) { - stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed, - start + stats.executionTimeInWindowMs - allowedTimeMinMs - + stats.windowSizeMs); - } if (stats.bgJobCountInWindow >= stats.jobCountLimit) { final long inQuotaTime = session.endTimeElapsed + stats.windowSizeMs; stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed, inQuotaTime); - stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed, - inQuotaTime); - stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed, - inQuotaTime); } if (i == loopStart || (sessions.get(i + 1).startTimeElapsed - session.endTimeElapsed) @@ -1413,10 +1304,6 @@ public final class QuotaController extends StateController { if (sessionCountInWindow >= stats.sessionCountLimit) { final long inQuotaTime = session.endTimeElapsed + stats.windowSizeMs; stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed, inQuotaTime); - stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed, - inQuotaTime); - stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed, - inQuotaTime); } } } @@ -1706,7 +1593,7 @@ public final class QuotaController extends StateController { /** * Update the CONSTRAINT_WITHIN_QUOTA bit for all of the Jobs for a given package. * - * @return true if at least one job had its bit changed + * @return the set of jobs whose status changed */ @NonNull private ArraySet<JobStatus> maybeUpdateConstraintForPkgLocked(final long nowElapsed, @@ -1719,8 +1606,7 @@ public final class QuotaController extends StateController { // Quota is the same for all jobs within a package. final int realStandbyBucket = jobs.valueAt(0).getStandbyBucket(); - final boolean realInQuota = isWithinQuotaLocked( - userId, packageName, realStandbyBucket, JobInfo.PRIORITY_DEFAULT); + final boolean realInQuota = isWithinQuotaLocked(userId, packageName, realStandbyBucket); boolean outOfEJQuota = false; for (int i = jobs.size() - 1; i >= 0; --i) { final JobStatus js = jobs.valueAt(i); @@ -1733,8 +1619,7 @@ public final class QuotaController extends StateController { changedJobs.add(js); } } else if (realStandbyBucket != EXEMPTED_INDEX && realStandbyBucket != ACTIVE_INDEX - && realStandbyBucket == js.getEffectiveStandbyBucket() - && js.getEffectivePriority() >= JobInfo.PRIORITY_DEFAULT) { + && 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. @@ -1798,8 +1683,9 @@ public final class QuotaController extends StateController { final String packageName = jobStatus.getSourcePackageName(); final int realStandbyBucket = jobStatus.getStandbyBucket(); if (isWithinEJQuota - && isWithinQuotaLocked(userId, packageName, realStandbyBucket, - JobInfo.PRIORITY_MIN)) { + && isWithinQuotaLocked(userId, packageName, realStandbyBucket)) { + // TODO(141645789): we probably shouldn't cancel the alarm until we've verified + // that all jobs for the userId-package are within quota. mInQuotaAlarmQueue.removeAlarmForKey(new Package(userId, packageName)); } else { mToScheduleStartAlarms.add(userId, packageName, realStandbyBucket); @@ -1860,25 +1746,8 @@ public final class QuotaController extends StateController { standbyBucket); final long remainingEJQuota = getRemainingEJExecutionTimeLocked(userId, packageName); - int minPriority = JobInfo.PRIORITY_MAX; - boolean hasDefPlus = false, hasLow = false, hasMin = false; - for (int i = jobs.size() - 1; i >= 0; --i) { - final int priority = jobs.valueAt(i).getEffectivePriority(); - minPriority = Math.min(minPriority, priority); - if (priority <= JobInfo.PRIORITY_MIN) { - hasMin = true; - } else if (priority <= JobInfo.PRIORITY_LOW) { - hasLow = true; - } else { - hasDefPlus = true; - } - if (hasMin && hasLow && hasDefPlus) { - break; - } - } final boolean inRegularQuota = - stats.executionTimeInWindowMs - < getAllowedTimePerPeriodMs(standbyBucket, minPriority) + stats.executionTimeInWindowMs < mAllowedTimePerPeriodMs[standbyBucket] && stats.executionTimeInMaxPeriodMs < mMaxExecutionTimeMs && isUnderJobCountQuota && isUnderTimingSessionCountQuota; @@ -1900,24 +1769,7 @@ public final class QuotaController extends StateController { long inEJQuotaTimeElapsed = Long.MAX_VALUE; if (!inRegularQuota) { // The time this app will have quota again. - long executionInQuotaTime = Long.MAX_VALUE; - boolean hasExecutionInQuotaTime = false; - if (hasMin && stats.inQuotaTimeMinElapsed > 0) { - executionInQuotaTime = Math.min(executionInQuotaTime, stats.inQuotaTimeMinElapsed); - hasExecutionInQuotaTime = true; - } - if (hasLow && stats.inQuotaTimeLowElapsed > 0) { - executionInQuotaTime = Math.min(executionInQuotaTime, stats.inQuotaTimeLowElapsed); - hasExecutionInQuotaTime = true; - } - if (hasDefPlus && stats.inQuotaTimeElapsed > 0) { - executionInQuotaTime = Math.min(executionInQuotaTime, stats.inQuotaTimeElapsed); - hasExecutionInQuotaTime = true; - } - long inQuotaTimeElapsed = 0; - if (hasExecutionInQuotaTime) { - inQuotaTimeElapsed = executionInQuotaTime; - } + long inQuotaTimeElapsed = stats.inQuotaTimeElapsed; if (!isUnderJobCountQuota && stats.bgJobCountInWindow < stats.jobCountLimit) { // App hit the rate limit. inQuotaTimeElapsed = @@ -2130,7 +1982,6 @@ public final class QuotaController extends StateController { private final ArraySet<JobStatus> mRunningBgJobs = new ArraySet<>(); private long mStartTimeElapsed; private int mBgJobCount; - private int mLowestPriority = JobInfo.PRIORITY_MAX; private long mDebitAdjustment; Timer(int uid, int userId, String packageName, boolean regularJobTimer) { @@ -2153,8 +2004,6 @@ public final class QuotaController extends StateController { Slog.v(TAG, "Starting to track " + jobStatus.toShortString()); } // Always maintain list of running jobs, even when quota is free. - final boolean priorityLowered = mLowestPriority > jobStatus.getEffectivePriority(); - mLowestPriority = Math.min(mLowestPriority, jobStatus.getEffectivePriority()); if (mRunningBgJobs.add(jobStatus) && shouldTrackLocked()) { mBgJobCount++; if (mRegularJobTimer) { @@ -2170,8 +2019,6 @@ public final class QuotaController extends StateController { invalidateAllExecutionStatsLocked(mPkg.userId, mPkg.packageName); } scheduleCutoff(); - } else if (mRegularJobTimer && priorityLowered) { - rescheduleCutoff(); } } } @@ -2196,19 +2043,6 @@ public final class QuotaController extends StateController { && !isQuotaFreeLocked(standbyBucket)) { emitSessionLocked(nowElapsed); cancelCutoff(); - mLowestPriority = JobInfo.PRIORITY_MAX; - } else if (mRegularJobTimer - && mLowestPriority == jobStatus.getEffectivePriority()) { - // Lowest priority doesn't matter for EJ timers. - final int oldPriority = mLowestPriority; - mLowestPriority = JobInfo.PRIORITY_MAX; - for (int i = mRunningBgJobs.size() - 1; i >= 0; --i) { - mLowestPriority = Math.min(mLowestPriority, - mRunningBgJobs.valueAt(i).getEffectivePriority()); - } - if (mLowestPriority != oldPriority) { - rescheduleCutoff(); - } } } } @@ -2335,14 +2169,9 @@ public final class QuotaController extends StateController { } Message msg = mHandler.obtainMessage( mRegularJobTimer ? MSG_REACHED_QUOTA : MSG_REACHED_EJ_QUOTA, mPkg); - final long timeRemainingMs; - if (mRegularJobTimer) { - timeRemainingMs = getTimeUntilQuotaConsumedLocked( - mPkg.userId, mPkg.packageName, mLowestPriority); - } else { - timeRemainingMs = - getTimeUntilEJQuotaConsumedLocked(mPkg.userId, mPkg.packageName); - } + final long timeRemainingMs = mRegularJobTimer + ? getTimeUntilQuotaConsumedLocked(mPkg.userId, mPkg.packageName) + : getTimeUntilEJQuotaConsumedLocked(mPkg.userId, mPkg.packageName); if (DEBUG) { Slog.i(TAG, (mRegularJobTimer ? "Regular job" : "EJ") + " for " + mPkg + " has " @@ -2695,19 +2524,26 @@ public final class QuotaController extends StateController { Slog.d(TAG, "Checking if " + pkg + " has reached its quota."); } - final ArraySet<JobStatus> changedJobs = maybeUpdateConstraintForPkgLocked( - sElapsedRealtimeClock.millis(), pkg.userId, pkg.packageName); - if (changedJobs.size() > 0) { + long timeRemainingMs = getRemainingExecutionTimeLocked(pkg.userId, + pkg.packageName); + if (timeRemainingMs <= 50) { + // Less than 50 milliseconds left. Start process of shutting down jobs. if (DEBUG) Slog.d(TAG, pkg + " has reached its quota."); - mStateChangedListener.onControllerStateChanged(changedJobs); + mStateChangedListener.onControllerStateChanged( + maybeUpdateConstraintForPkgLocked( + sElapsedRealtimeClock.millis(), + pkg.userId, pkg.packageName)); } else { // This could potentially happen if an old session phases out while a // job is currently running. // Reschedule message + Message rescheduleMsg = obtainMessage(MSG_REACHED_QUOTA, pkg); + timeRemainingMs = getTimeUntilQuotaConsumedLocked(pkg.userId, + pkg.packageName); if (DEBUG) { - Slog.d(TAG, pkg + " had early REACHED_QUOTA message"); + Slog.d(TAG, pkg + " has " + timeRemainingMs + "ms left."); } - mPkgTimers.get(pkg.userId, pkg.packageName).rescheduleCutoff(); + sendMessageDelayed(rescheduleMsg, timeRemainingMs); } break; } @@ -2717,19 +2553,25 @@ public final class QuotaController extends StateController { Slog.d(TAG, "Checking if " + pkg + " has reached its EJ quota."); } - final ArraySet<JobStatus> changedJobs = maybeUpdateConstraintForPkgLocked( - sElapsedRealtimeClock.millis(), pkg.userId, pkg.packageName); - if (changedJobs.size() > 0) { + long timeRemainingMs = getRemainingEJExecutionTimeLocked( + pkg.userId, pkg.packageName); + if (timeRemainingMs <= 0) { if (DEBUG) Slog.d(TAG, pkg + " has reached its EJ quota."); - mStateChangedListener.onControllerStateChanged(changedJobs); + mStateChangedListener.onControllerStateChanged( + maybeUpdateConstraintForPkgLocked( + sElapsedRealtimeClock.millis(), + pkg.userId, pkg.packageName)); } else { // This could potentially happen if an old session phases out while a // job is currently running. // Reschedule message + Message rescheduleMsg = obtainMessage(MSG_REACHED_EJ_QUOTA, pkg); + timeRemainingMs = getTimeUntilEJQuotaConsumedLocked( + pkg.userId, pkg.packageName); if (DEBUG) { - Slog.d(TAG, pkg + " had early REACHED_EJ_QUOTA message"); + Slog.d(TAG, pkg + " has " + timeRemainingMs + "ms left for EJ"); } - mEJPkgTimers.get(pkg.userId, pkg.packageName).rescheduleCutoff(); + sendMessageDelayed(rescheduleMsg, timeRemainingMs); } break; } @@ -2993,12 +2835,6 @@ public final class QuotaController extends StateController { static final String KEY_IN_QUOTA_BUFFER_MS = QC_CONSTANT_PREFIX + "in_quota_buffer_ms"; @VisibleForTesting - static final String KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW = - QC_CONSTANT_PREFIX + "allowed_time_surplus_priority_low"; - @VisibleForTesting - static final String KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN = - QC_CONSTANT_PREFIX + "allowed_time_surplus_priority_min"; - @VisibleForTesting static final String KEY_WINDOW_SIZE_EXEMPTED_MS = QC_CONSTANT_PREFIX + "window_size_exempted_ms"; @VisibleForTesting @@ -3130,8 +2966,6 @@ public final class QuotaController extends StateController { 10 * 60 * 1000L; // 10 minutes private static final long DEFAULT_IN_QUOTA_BUFFER_MS = 30 * 1000L; // 30 seconds - private static final float DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_LOW = .25f; - private static final float DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_MIN = .5f; private static final long DEFAULT_WINDOW_SIZE_EXEMPTED_MS = DEFAULT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS; // EXEMPT apps can run jobs at any time private static final long DEFAULT_WINDOW_SIZE_ACTIVE_MS = @@ -3230,22 +3064,6 @@ public final class QuotaController extends StateController { public long IN_QUOTA_BUFFER_MS = DEFAULT_IN_QUOTA_BUFFER_MS; /** - * The percentage of ALLOWED_TIME_PER_PERIOD_*_MS that should not be used by - * {@link JobInfo#PRIORITY_LOW low priority} jobs. In other words, there must be a minimum - * surplus of this amount of remaining allowed time before we start running low priority - * jobs. - */ - public float ALLOWED_TIME_SURPLUS_PRIORITY_LOW = DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_LOW; - - /** - * The percentage of ALLOWED_TIME_PER_PERIOD_*_MS that should not be used by - * {@link JobInfo#PRIORITY_MIN low priority} jobs. In other words, there must be a minimum - * surplus of this amount of remaining allowed time before we start running min priority - * jobs. - */ - public float ALLOWED_TIME_SURPLUS_PRIORITY_MIN = DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_MIN; - - /** * The quota window size of the particular standby bucket. Apps in this standby bucket are * expected to run only {@link #ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS} within the past * WINDOW_SIZE_MS. @@ -3514,8 +3332,6 @@ public final class QuotaController extends StateController { case KEY_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS: case KEY_ALLOWED_TIME_PER_PERIOD_RARE_MS: case KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS: - case KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW: - case KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN: case KEY_IN_QUOTA_BUFFER_MS: case KEY_MAX_EXECUTION_TIME_MS: case KEY_WINDOW_SIZE_ACTIVE_MS: @@ -3757,7 +3573,6 @@ public final class QuotaController extends StateController { KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS, KEY_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS, KEY_ALLOWED_TIME_PER_PERIOD_RARE_MS, KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS, KEY_IN_QUOTA_BUFFER_MS, - KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW, KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN, KEY_MAX_EXECUTION_TIME_MS, KEY_WINDOW_SIZE_EXEMPTED_MS, KEY_WINDOW_SIZE_ACTIVE_MS, KEY_WINDOW_SIZE_WORKING_MS, @@ -3781,12 +3596,6 @@ public final class QuotaController extends StateController { ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS = properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS, DEFAULT_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS); - ALLOWED_TIME_SURPLUS_PRIORITY_LOW = - properties.getFloat(KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW, - DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_LOW); - ALLOWED_TIME_SURPLUS_PRIORITY_MIN = - properties.getFloat(KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN, - DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_MIN); IN_QUOTA_BUFFER_MS = properties.getLong(KEY_IN_QUOTA_BUFFER_MS, DEFAULT_IN_QUOTA_BUFFER_MS); MAX_EXECUTION_TIME_MS = properties.getLong(KEY_MAX_EXECUTION_TIME_MS, @@ -3865,23 +3674,6 @@ public final class QuotaController extends StateController { mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs; mShouldReevaluateConstraints = true; } - // Low priority surplus should be in the range [0, .9]. A value of 1 would essentially - // mean never run low priority jobs. - float newAllowedTimeSurplusPriorityLow = - Math.max(0f, Math.min(.9f, ALLOWED_TIME_SURPLUS_PRIORITY_LOW)); - if (Float.compare( - mAllowedTimeSurplusPriorityLow, newAllowedTimeSurplusPriorityLow) != 0) { - mAllowedTimeSurplusPriorityLow = newAllowedTimeSurplusPriorityLow; - mShouldReevaluateConstraints = true; - } - // Min priority surplus should be in the range [0, mAllowedTimeSurplusPriorityLow]. - float newAllowedTimeSurplusPriorityMin = Math.max(0f, - Math.min(mAllowedTimeSurplusPriorityLow, ALLOWED_TIME_SURPLUS_PRIORITY_MIN)); - if (Float.compare( - mAllowedTimeSurplusPriorityMin, newAllowedTimeSurplusPriorityMin) != 0) { - mAllowedTimeSurplusPriorityMin = newAllowedTimeSurplusPriorityMin; - mShouldReevaluateConstraints = true; - } long newExemptedPeriodMs = Math.max(mAllowedTimePerPeriodMs[EXEMPTED_INDEX], Math.min(MAX_PERIOD_MS, WINDOW_SIZE_EXEMPTED_MS)); if (mBucketPeriodsMs[EXEMPTED_INDEX] != newExemptedPeriodMs) { @@ -4081,10 +3873,6 @@ public final class QuotaController extends StateController { .println(); pw.print(KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS, ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS).println(); - pw.print(KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW, ALLOWED_TIME_SURPLUS_PRIORITY_LOW) - .println(); - pw.print(KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN, ALLOWED_TIME_SURPLUS_PRIORITY_MIN) - .println(); pw.print(KEY_IN_QUOTA_BUFFER_MS, IN_QUOTA_BUFFER_MS).println(); pw.print(KEY_WINDOW_SIZE_EXEMPTED_MS, WINDOW_SIZE_EXEMPTED_MS).println(); pw.print(KEY_WINDOW_SIZE_ACTIVE_MS, WINDOW_SIZE_ACTIVE_MS).println(); @@ -4210,16 +3998,6 @@ public final class QuotaController extends StateController { } @VisibleForTesting - float getAllowedTimeSurplusPriorityLow() { - return mAllowedTimeSurplusPriorityLow; - } - - @VisibleForTesting - float getAllowedTimeSurplusPriorityMin() { - return mAllowedTimeSurplusPriorityMin; - } - - @VisibleForTesting @NonNull int[] getBucketMaxJobCounts() { return mMaxBucketJobCounts; 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 a0ac50634a7b..9a4f8e261124 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 @@ -16,11 +16,6 @@ package com.android.server.job.controllers; -import static android.app.job.JobInfo.PRIORITY_DEFAULT; -import static android.app.job.JobInfo.PRIORITY_HIGH; -import static android.app.job.JobInfo.PRIORITY_LOW; -import static android.app.job.JobInfo.PRIORITY_MIN; - import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; @@ -275,14 +270,14 @@ public class QuotaControllerTest { } private void setCharging() { - when(mJobSchedulerService.isBatteryCharging()).thenReturn(true); + doReturn(true).when(mJobSchedulerService).isBatteryCharging(); synchronized (mQuotaController.mLock) { mQuotaController.onBatteryStateChangedLocked(); } } private void setDischarging() { - when(mJobSchedulerService.isBatteryCharging()).thenReturn(false); + doReturn(false).when(mJobSchedulerService).isBatteryCharging(); synchronized (mQuotaController.mLock) { mQuotaController.onBatteryStateChangedLocked(); } @@ -415,14 +410,6 @@ public class QuotaControllerTest { } } - private void setDeviceConfigFloat(String key, float val) { - mDeviceConfigPropertiesBuilder.setFloat(key, val); - synchronized (mQuotaController.mLock) { - mQuotaController.prepareForUpdatedConstantsLocked(); - mQcConstants.processConstantLocked(mDeviceConfigPropertiesBuilder.build(), key); - } - } - private void waitForNonDelayedMessagesProcessed() { mQuotaController.getHandler().runWithScissors(() -> {}, 15_000); } @@ -861,7 +848,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE, inputStats); assertEquals(expectedStats, inputStats); assertTrue(mQuotaController.isWithinQuotaLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX)); } assertTrue("Job not ready: " + jobStatus, jobStatus.isReady()); } @@ -885,7 +872,7 @@ public class QuotaControllerTest { assertEquals(expectedStats, inputStats); assertFalse( mQuotaController.isWithinQuotaLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX)); } // Quota should be exceeded due to activity in active timer. @@ -910,7 +897,7 @@ public class QuotaControllerTest { assertEquals(expectedStats, inputStats); assertFalse( mQuotaController.isWithinQuotaLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX)); assertFalse("Job unexpectedly ready: " + jobStatus, jobStatus.isReady()); } } @@ -1508,7 +1495,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 30 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } } @@ -1541,7 +1528,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } setStandbyBucket(FREQUENT_INDEX); @@ -1551,7 +1538,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } setStandbyBucket(WORKING_INDEX); @@ -1561,7 +1548,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(7 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } // ACTIVE window = allowed time, so jobs can essentially run non-stop until they reach the @@ -1573,7 +1560,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 9 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } } @@ -1597,7 +1584,7 @@ public class QuotaControllerTest { // Max time will phase out, so should use bucket limit. assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); @@ -1613,7 +1600,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); @@ -1630,7 +1617,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(3 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } } @@ -1663,7 +1650,7 @@ public class QuotaControllerTest { // window time. assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear(); @@ -1690,107 +1677,7 @@ public class QuotaControllerTest { // Max time only has one minute phase out. Bucket time has 2 minute phase out. assertEquals(9 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); - } - } - - /** - * Test getTimeUntilQuotaConsumedLocked when the determination is based on the job's priority. - */ - @Test - public void testGetTimeUntilQuotaConsumedLocked_Priority() { - final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); - // Close to RARE boundary. - mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, - createTimingSession(now - (24 * HOUR_IN_MILLIS - 30 * SECOND_IN_MILLIS), - 150 * SECOND_IN_MILLIS, 5), false); - // Far away from FREQUENT boundary. - mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, - createTimingSession(now - (7 * HOUR_IN_MILLIS), 2 * MINUTE_IN_MILLIS, 5), false); - // Overlap WORKING_SET boundary. - mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, - createTimingSession(now - (2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS), - 2 * MINUTE_IN_MILLIS, 5), false); - // Close to ACTIVE boundary. - mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, - createTimingSession(now - (9 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false); - - setStandbyBucket(RARE_INDEX); - synchronized (mQuotaController.mLock) { - assertEquals(30 * SECOND_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked( - SOURCE_USER_ID, SOURCE_PACKAGE)); - assertEquals(3 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_HIGH)); - assertEquals(3 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); - assertEquals(0, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_LOW)); - assertEquals(0, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_MIN)); - } - - setStandbyBucket(FREQUENT_INDEX); - synchronized (mQuotaController.mLock) { - assertEquals(3 * MINUTE_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked( - SOURCE_USER_ID, SOURCE_PACKAGE)); - assertEquals(3 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_HIGH)); - assertEquals(3 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); - assertEquals(30 * SECOND_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_LOW)); - assertEquals(0, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_MIN)); - } - - setStandbyBucket(WORKING_INDEX); - synchronized (mQuotaController.mLock) { - assertEquals(6 * MINUTE_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked( SOURCE_USER_ID, SOURCE_PACKAGE)); - assertEquals(7 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_HIGH)); - assertEquals(7 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); - assertEquals(4 * MINUTE_IN_MILLIS + 30 * SECOND_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_LOW)); - assertEquals(2 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_MIN)); - } - - // ACTIVE window = allowed time, so jobs can essentially run non-stop until they reach the - // max execution time. - setStandbyBucket(ACTIVE_INDEX); - synchronized (mQuotaController.mLock) { - assertEquals(7 * MINUTE_IN_MILLIS, - mQuotaController.getRemainingExecutionTimeLocked( - SOURCE_USER_ID, SOURCE_PACKAGE)); - assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 7 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_HIGH)); - assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 7 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); - assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 7 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_LOW)); - assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 7 * MINUTE_IN_MILLIS, - mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_MIN)); } } @@ -1820,7 +1707,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 10 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } } @@ -1842,7 +1729,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, @@ -1854,7 +1741,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, @@ -1867,7 +1754,7 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, @@ -1882,15 +1769,15 @@ public class QuotaControllerTest { SOURCE_USER_ID, SOURCE_PACKAGE)); assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 30 * MINUTE_IN_MILLIS, mQuotaController.getTimeUntilQuotaConsumedLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT)); + SOURCE_USER_ID, SOURCE_PACKAGE)); } } @Test public void testIsWithinQuotaLocked_NeverApp() { synchronized (mQuotaController.mLock) { - assertFalse(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test.never", NEVER_INDEX, PRIORITY_DEFAULT)); + assertFalse( + mQuotaController.isWithinQuotaLocked(0, "com.android.test.never", NEVER_INDEX)); } } @@ -1898,8 +1785,7 @@ public class QuotaControllerTest { public void testIsWithinQuotaLocked_Charging() { setCharging(); synchronized (mQuotaController.mLock) { - assertTrue(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", RARE_INDEX, PRIORITY_DEFAULT)); + assertTrue(mQuotaController.isWithinQuotaLocked(0, "com.android.test", RARE_INDEX)); } } @@ -1913,8 +1799,7 @@ public class QuotaControllerTest { createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false); synchronized (mQuotaController.mLock) { mQuotaController.incrementJobCountLocked(0, "com.android.test", 5); - assertTrue(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", WORKING_INDEX, PRIORITY_DEFAULT)); + assertTrue(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); } } @@ -1931,7 +1816,7 @@ public class QuotaControllerTest { synchronized (mQuotaController.mLock) { mQuotaController.incrementJobCountLocked(0, "com.android.test.spam", jobCount); assertFalse(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test.spam", WORKING_INDEX, PRIORITY_DEFAULT)); + 0, "com.android.test.spam", WORKING_INDEX)); } mQuotaController.saveTimingSession(0, "com.android.test.frequent", @@ -1941,7 +1826,7 @@ public class QuotaControllerTest { createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 500), false); synchronized (mQuotaController.mLock) { assertFalse(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test.frequent", FREQUENT_INDEX, PRIORITY_DEFAULT)); + 0, "com.android.test.frequent", FREQUENT_INDEX)); } } @@ -1957,8 +1842,7 @@ public class QuotaControllerTest { createTimingSession(now - (5 * MINUTE_IN_MILLIS), 4 * MINUTE_IN_MILLIS, 5), false); synchronized (mQuotaController.mLock) { mQuotaController.incrementJobCountLocked(0, "com.android.test", 5); - assertFalse(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", WORKING_INDEX, PRIORITY_DEFAULT)); + assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); } } @@ -1974,8 +1858,7 @@ public class QuotaControllerTest { false); synchronized (mQuotaController.mLock) { mQuotaController.incrementJobCountLocked(0, "com.android.test", jobCount); - assertFalse(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", WORKING_INDEX, PRIORITY_DEFAULT)); + assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); } } @@ -2128,66 +2011,22 @@ public class QuotaControllerTest { assertEquals("Rare has incorrect quota status with " + (i + 1) + " sessions", i < 2, - mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", RARE_INDEX, PRIORITY_DEFAULT)); + mQuotaController.isWithinQuotaLocked(0, "com.android.test", RARE_INDEX)); assertEquals("Frequent has incorrect quota status with " + (i + 1) + " sessions", i < 3, mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", FREQUENT_INDEX, PRIORITY_DEFAULT)); + 0, "com.android.test", FREQUENT_INDEX)); assertEquals("Working has incorrect quota status with " + (i + 1) + " sessions", i < 4, - mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", WORKING_INDEX, PRIORITY_DEFAULT)); + mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX)); assertEquals("Active has incorrect quota status with " + (i + 1) + " sessions", i < 5, - mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", ACTIVE_INDEX, PRIORITY_DEFAULT)); + mQuotaController.isWithinQuotaLocked(0, "com.android.test", ACTIVE_INDEX)); } } } @Test - public void testIsWithinQuotaLocked_Priority() { - setDischarging(); - final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.saveTimingSession(0, "com.android.test", - createTimingSession(now - (7 * HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false); - mQuotaController.saveTimingSession(0, "com.android.test", - createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false); - mQuotaController.saveTimingSession(0, "com.android.test", - createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false); - synchronized (mQuotaController.mLock) { - mQuotaController.incrementJobCountLocked(0, "com.android.test", 5); - assertTrue(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", FREQUENT_INDEX, PRIORITY_HIGH)); - assertTrue(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", FREQUENT_INDEX, PRIORITY_DEFAULT)); - assertFalse(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", FREQUENT_INDEX, PRIORITY_LOW)); - assertFalse(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", FREQUENT_INDEX, PRIORITY_MIN)); - - assertTrue(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", WORKING_INDEX, PRIORITY_HIGH)); - assertTrue(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", WORKING_INDEX, PRIORITY_DEFAULT)); - assertTrue(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", WORKING_INDEX, PRIORITY_LOW)); - assertFalse(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", WORKING_INDEX, PRIORITY_MIN)); - - assertTrue(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", ACTIVE_INDEX, PRIORITY_HIGH)); - assertTrue(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", ACTIVE_INDEX, PRIORITY_DEFAULT)); - assertTrue(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", ACTIVE_INDEX, PRIORITY_LOW)); - assertTrue(mQuotaController.isWithinQuotaLocked( - 0, "com.android.test", ACTIVE_INDEX, PRIORITY_MIN)); - } - } - - @Test public void testIsWithinEJQuotaLocked_NeverApp() { JobStatus js = createExpeditedJobStatus("testIsWithinEJQuotaLocked_NeverApp", 1); setStandbyBucket(NEVER_INDEX, js); @@ -2737,8 +2576,7 @@ public class QuotaControllerTest { mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, createTimingSession(now - 25 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1), false); synchronized (mQuotaController.mLock) { - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket); + mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket); } verify(mAlarmManager, timeout(1000).times(0)).setWindow( anyInt(), anyLong(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); @@ -2790,128 +2628,6 @@ public class QuotaControllerTest { anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); } - @Test - public void testMaybeScheduleStartAlarmLocked_Priority() { - // saveTimingSession calls maybeScheduleCleanupAlarmLocked which interferes with these tests - // because it schedules an alarm too. Prevent it from doing so. - spyOn(mQuotaController); - doNothing().when(mQuotaController).maybeScheduleCleanupAlarmLocked(); - - setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_RARE, 5); - - final long now = JobSchedulerService.sElapsedRealtimeClock.millis(); - mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, - createTimingSession(now - (24 * HOUR_IN_MILLIS), MINUTE_IN_MILLIS, 1), false); - mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, - createTimingSession(now - (7 * HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 1), false); - mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, - createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 1), false); - mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE, - createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 1), false); - - InOrder inOrder = inOrder(mAlarmManager); - - JobStatus jobDef = createJobStatus("testMaybeScheduleStartAlarmLocked_Priority", - SOURCE_PACKAGE, CALLING_UID, - new JobInfo.Builder(1, new ComponentName(mContext, "TestQuotaJobService")) - .setPriority(PRIORITY_DEFAULT) - .build()); - JobStatus jobLow = createJobStatus("testMaybeScheduleStartAlarmLocked_Priority", - SOURCE_PACKAGE, CALLING_UID, - new JobInfo.Builder(2, new ComponentName(mContext, "TestQuotaJobService")) - .setPriority(PRIORITY_LOW) - .build()); - JobStatus jobMin = createJobStatus("testMaybeScheduleStartAlarmLocked_Priority", - SOURCE_PACKAGE, CALLING_UID, - new JobInfo.Builder(3, new ComponentName(mContext, "TestQuotaJobService")) - .setPriority(PRIORITY_MIN) - .build()); - - setStandbyBucket(RARE_INDEX, jobDef, jobLow, jobMin); - synchronized (mQuotaController.mLock) { - mQuotaController.maybeStartTrackingJobLocked(jobMin, null); - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX); - // Min job requires 5 mins of surplus. - long expectedAlarmTime = now + 23 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS; - inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow( - anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); - - mQuotaController.maybeStartTrackingJobLocked(jobLow, null); - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX); - // Low job requires 2.5 mins of surplus. - expectedAlarmTime = now + 17 * HOUR_IN_MILLIS + 90 * SECOND_IN_MILLIS; - inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow( - anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); - - mQuotaController.maybeStartTrackingJobLocked(jobDef, null); - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX); - // Default+ jobs require IN_QUOTA_BUFFER_MS. - expectedAlarmTime = now + mQcConstants.IN_QUOTA_BUFFER_MS; - inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow( - anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); - - mQuotaController.maybeStopTrackingJobLocked(jobMin, null, false); - mQuotaController.maybeStopTrackingJobLocked(jobLow, null, false); - mQuotaController.maybeStopTrackingJobLocked(jobDef, null, false); - - setStandbyBucket(FREQUENT_INDEX, jobDef, jobLow, jobMin); - - mQuotaController.maybeStartTrackingJobLocked(jobMin, null); - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, FREQUENT_INDEX); - // Min job requires 5 mins of surplus. - expectedAlarmTime = now + 7 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS; - inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow( - anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); - - mQuotaController.maybeStartTrackingJobLocked(jobLow, null); - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, FREQUENT_INDEX); - // Low job requires 2.5 mins of surplus. - expectedAlarmTime = now + HOUR_IN_MILLIS + 90 * SECOND_IN_MILLIS; - inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow( - anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); - - mQuotaController.maybeStartTrackingJobLocked(jobDef, null); - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, FREQUENT_INDEX); - // Default+ jobs already have enough quota. - inOrder.verify(mAlarmManager, timeout(1000).times(0)).setWindow( - anyInt(), anyLong(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); - - mQuotaController.maybeStopTrackingJobLocked(jobMin, null, false); - mQuotaController.maybeStopTrackingJobLocked(jobLow, null, false); - mQuotaController.maybeStopTrackingJobLocked(jobDef, null, false); - - setStandbyBucket(WORKING_INDEX, jobDef, jobLow, jobMin); - - mQuotaController.maybeStartTrackingJobLocked(jobMin, null); - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX); - // Min job requires 5 mins of surplus. - expectedAlarmTime = now + HOUR_IN_MILLIS + MINUTE_IN_MILLIS; - inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow( - anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); - - mQuotaController.maybeStartTrackingJobLocked(jobLow, null); - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX); - // Low job has enough surplus. - inOrder.verify(mAlarmManager, timeout(1000).times(0)).setWindow( - anyInt(), anyLong(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); - - mQuotaController.maybeStartTrackingJobLocked(jobDef, null); - mQuotaController.maybeScheduleStartAlarmLocked( - SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX); - // Default+ jobs already have enough quota. - inOrder.verify(mAlarmManager, timeout(1000).times(0)).setWindow( - anyInt(), anyLong(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any()); - } - } - /** Tests that the start alarm is properly rescheduled if the app's bucket is changed. */ @Test public void testMaybeScheduleStartAlarmLocked_BucketChange() { @@ -3212,8 +2928,6 @@ public class QuotaControllerTest { setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS, 11 * MINUTE_IN_MILLIS); setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, 2 * MINUTE_IN_MILLIS); - setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW, .7f); - setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN, .2f); setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_EXEMPTED_MS, 99 * MINUTE_IN_MILLIS); setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_ACTIVE_MS, 15 * MINUTE_IN_MILLIS); setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_WORKING_MS, 30 * MINUTE_IN_MILLIS); @@ -3269,8 +2983,6 @@ public class QuotaControllerTest { assertEquals(11 * MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs()[RESTRICTED_INDEX]); assertEquals(2 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs()); - assertEquals(.7f, mQuotaController.getAllowedTimeSurplusPriorityLow(), 1e-6); - assertEquals(.2f, mQuotaController.getAllowedTimeSurplusPriorityMin(), 1e-6); assertEquals(99 * MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[EXEMPTED_INDEX]); assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[ACTIVE_INDEX]); @@ -3327,8 +3039,6 @@ public class QuotaControllerTest { setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS, -MINUTE_IN_MILLIS); setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, -MINUTE_IN_MILLIS); - setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW, -.1f); - setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN, -.01f); setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_EXEMPTED_MS, -MINUTE_IN_MILLIS); setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_ACTIVE_MS, -MINUTE_IN_MILLIS); setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_WORKING_MS, -MINUTE_IN_MILLIS); @@ -3379,8 +3089,6 @@ public class QuotaControllerTest { assertEquals(MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs()[RESTRICTED_INDEX]); assertEquals(0, mQuotaController.getInQuotaBufferMs()); - assertEquals(0f, mQuotaController.getAllowedTimeSurplusPriorityLow(), 1e-6); - assertEquals(0f, mQuotaController.getAllowedTimeSurplusPriorityMin(), 1e-6); assertEquals(MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[EXEMPTED_INDEX]); assertEquals(MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[ACTIVE_INDEX]); assertEquals(MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[WORKING_INDEX]); @@ -3451,8 +3159,6 @@ public class QuotaControllerTest { setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS, 25 * HOUR_IN_MILLIS); setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, 25 * HOUR_IN_MILLIS); - setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW, 1f); - setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN, .95f); setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_EXEMPTED_MS, 25 * HOUR_IN_MILLIS); setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_ACTIVE_MS, 25 * HOUR_IN_MILLIS); setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_WORKING_MS, 25 * HOUR_IN_MILLIS); @@ -3492,8 +3198,6 @@ public class QuotaControllerTest { assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs()[RESTRICTED_INDEX]); assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs()); - assertEquals(.9f, mQuotaController.getAllowedTimeSurplusPriorityLow(), 1e-6); - assertEquals(.9f, mQuotaController.getAllowedTimeSurplusPriorityMin(), 1e-6); assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getBucketWindowSizes()[EXEMPTED_INDEX]); assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getBucketWindowSizes()[ACTIVE_INDEX]); assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getBucketWindowSizes()[WORKING_INDEX]); |