Merge "Split allowed time by standby bucket."
This commit is contained in:
@@ -357,6 +357,9 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
// Putting RESTRICTED_INDEX after NEVER_INDEX to make it easier for proto dumping
|
||||
// (ScheduledJobStateChanged and JobStatusDumpProto).
|
||||
public static final int RESTRICTED_INDEX = 5;
|
||||
// Putting EXEMPTED_INDEX after RESTRICTED_INDEX to make it easier for proto dumping
|
||||
// (ScheduledJobStateChanged and JobStatusDumpProto).
|
||||
public static final int EXEMPTED_INDEX = 6;
|
||||
|
||||
private class ConstantsObserver implements DeviceConfig.OnPropertiesChangedListener,
|
||||
EconomyManagerInternal.TareStateChangeListener {
|
||||
@@ -2492,6 +2495,7 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
shouldForceBatchJob =
|
||||
mConstants.MIN_READY_NON_ACTIVE_JOBS_COUNT > 1
|
||||
&& job.getEffectiveStandbyBucket() != ACTIVE_INDEX
|
||||
&& job.getEffectiveStandbyBucket() != EXEMPTED_INDEX
|
||||
&& !batchDelayExpired;
|
||||
}
|
||||
|
||||
@@ -3086,8 +3090,10 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
return FREQUENT_INDEX;
|
||||
} else if (bucket > UsageStatsManager.STANDBY_BUCKET_ACTIVE) {
|
||||
return WORKING_INDEX;
|
||||
} else {
|
||||
} else if (bucket > UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
|
||||
return ACTIVE_INDEX;
|
||||
} else {
|
||||
return EXEMPTED_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.job.controllers;
|
||||
|
||||
import static com.android.server.job.JobSchedulerService.ACTIVE_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.EXEMPTED_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.NEVER_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.WORKING_INDEX;
|
||||
@@ -844,12 +845,15 @@ public final class JobStatus {
|
||||
* exemptions.
|
||||
*/
|
||||
public int getEffectiveStandbyBucket() {
|
||||
final int actualBucket = getStandbyBucket();
|
||||
if (actualBucket == EXEMPTED_INDEX) {
|
||||
return actualBucket;
|
||||
}
|
||||
if (uidActive || getJob().isExemptedFromAppStandby()) {
|
||||
// Treat these cases as if they're in the ACTIVE bucket so that they get throttled
|
||||
// like other ACTIVE apps.
|
||||
return ACTIVE_INDEX;
|
||||
}
|
||||
final int actualBucket = getStandbyBucket();
|
||||
if (actualBucket != RESTRICTED_INDEX && actualBucket != NEVER_INDEX
|
||||
&& mHasMediaBackupExemption) {
|
||||
// Cap it at WORKING_INDEX as media back up jobs are important to the user, and the
|
||||
|
||||
@@ -21,6 +21,7 @@ import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
|
||||
|
||||
import static com.android.server.job.JobSchedulerService.ACTIVE_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.EXEMPTED_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.FREQUENT_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.NEVER_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.RARE_INDEX;
|
||||
@@ -132,6 +133,7 @@ public final class QuotaController extends StateController {
|
||||
*/
|
||||
public long expirationTimeElapsed;
|
||||
|
||||
public long allowedTimePerPeriodMs;
|
||||
public long windowSizeMs;
|
||||
public int jobCountLimit;
|
||||
public int sessionCountLimit;
|
||||
@@ -213,6 +215,7 @@ public final class QuotaController extends StateController {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "expirationTime=" + expirationTimeElapsed + ", "
|
||||
+ "allowedTimePerPeriodMs=" + allowedTimePerPeriodMs + ", "
|
||||
+ "windowSizeMs=" + windowSizeMs + ", "
|
||||
+ "jobCountLimit=" + jobCountLimit + ", "
|
||||
+ "sessionCountLimit=" + sessionCountLimit + ", "
|
||||
@@ -236,6 +239,7 @@ public final class QuotaController extends StateController {
|
||||
if (obj instanceof ExecutionStats) {
|
||||
ExecutionStats other = (ExecutionStats) obj;
|
||||
return this.expirationTimeElapsed == other.expirationTimeElapsed
|
||||
&& this.allowedTimePerPeriodMs == other.allowedTimePerPeriodMs
|
||||
&& this.windowSizeMs == other.windowSizeMs
|
||||
&& this.jobCountLimit == other.jobCountLimit
|
||||
&& this.sessionCountLimit == other.sessionCountLimit
|
||||
@@ -261,6 +265,7 @@ public final class QuotaController extends StateController {
|
||||
public int hashCode() {
|
||||
int result = 0;
|
||||
result = 31 * result + hashLong(expirationTimeElapsed);
|
||||
result = 31 * result + hashLong(allowedTimePerPeriodMs);
|
||||
result = 31 * result + hashLong(windowSizeMs);
|
||||
result = 31 * result + hashLong(jobCountLimit);
|
||||
result = 31 * result + hashLong(sessionCountLimit);
|
||||
@@ -350,7 +355,15 @@ public final class QuotaController extends StateController {
|
||||
private boolean mIsEnabled;
|
||||
|
||||
/** How much time each app will have to run jobs within their standby bucket window. */
|
||||
private long mAllowedTimePerPeriodMs = QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_MS;
|
||||
private final long[] mAllowedTimePerPeriodMs = new long[]{
|
||||
QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS,
|
||||
QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_WORKING_MS,
|
||||
QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS,
|
||||
QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_RARE_MS,
|
||||
0, // NEVER
|
||||
QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS,
|
||||
QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS
|
||||
};
|
||||
|
||||
/**
|
||||
* The maximum amount of time an app can have its jobs running within a {@link #MAX_PERIOD_MS}
|
||||
@@ -364,12 +377,6 @@ public final class QuotaController extends StateController {
|
||||
*/
|
||||
private long mQuotaBufferMs = QcConstants.DEFAULT_IN_QUOTA_BUFFER_MS;
|
||||
|
||||
/**
|
||||
* {@link #mAllowedTimePerPeriodMs} - {@link #mQuotaBufferMs}. This can be used to determine
|
||||
* when an app will have enough quota to transition from out-of-quota to in-quota.
|
||||
*/
|
||||
private long mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs;
|
||||
|
||||
/**
|
||||
* {@link #mMaxExecutionTimeMs} - {@link #mQuotaBufferMs}. This can be used to determine when an
|
||||
* app will have enough quota to transition from out-of-quota to in-quota.
|
||||
@@ -450,7 +457,8 @@ public final class QuotaController extends StateController {
|
||||
QcConstants.DEFAULT_WINDOW_SIZE_FREQUENT_MS,
|
||||
QcConstants.DEFAULT_WINDOW_SIZE_RARE_MS,
|
||||
0, // NEVER
|
||||
QcConstants.DEFAULT_WINDOW_SIZE_RESTRICTED_MS
|
||||
QcConstants.DEFAULT_WINDOW_SIZE_RESTRICTED_MS,
|
||||
QcConstants.DEFAULT_WINDOW_SIZE_EXEMPTED_MS
|
||||
};
|
||||
|
||||
/** The maximum period any bucket can have. */
|
||||
@@ -469,7 +477,8 @@ public final class QuotaController extends StateController {
|
||||
QcConstants.DEFAULT_MAX_JOB_COUNT_FREQUENT,
|
||||
QcConstants.DEFAULT_MAX_JOB_COUNT_RARE,
|
||||
0, // NEVER
|
||||
QcConstants.DEFAULT_MAX_JOB_COUNT_RESTRICTED
|
||||
QcConstants.DEFAULT_MAX_JOB_COUNT_RESTRICTED,
|
||||
QcConstants.DEFAULT_MAX_JOB_COUNT_EXEMPTED
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -487,6 +496,7 @@ public final class QuotaController extends StateController {
|
||||
QcConstants.DEFAULT_MAX_SESSION_COUNT_RARE,
|
||||
0, // NEVER
|
||||
QcConstants.DEFAULT_MAX_SESSION_COUNT_RESTRICTED,
|
||||
QcConstants.DEFAULT_MAX_SESSION_COUNT_EXEMPTED,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -506,7 +516,8 @@ public final class QuotaController extends StateController {
|
||||
QcConstants.DEFAULT_EJ_LIMIT_FREQUENT_MS,
|
||||
QcConstants.DEFAULT_EJ_LIMIT_RARE_MS,
|
||||
0, // NEVER
|
||||
QcConstants.DEFAULT_EJ_LIMIT_RESTRICTED_MS
|
||||
QcConstants.DEFAULT_EJ_LIMIT_RESTRICTED_MS,
|
||||
QcConstants.DEFAULT_EJ_LIMIT_EXEMPTED_MS
|
||||
};
|
||||
|
||||
private long mEjLimitAdditionInstallerMs = QcConstants.DEFAULT_EJ_LIMIT_ADDITION_INSTALLER_MS;
|
||||
@@ -823,6 +834,11 @@ public final class QuotaController extends StateController {
|
||||
if (mService.isBatteryCharging()) {
|
||||
return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS;
|
||||
}
|
||||
if (jobStatus.getEffectiveStandbyBucket() == EXEMPTED_INDEX) {
|
||||
return Math.max(mEJLimitsMs[EXEMPTED_INDEX] / 2,
|
||||
getTimeUntilEJQuotaConsumedLocked(
|
||||
jobStatus.getSourceUserId(), jobStatus.getSourcePackageName()));
|
||||
}
|
||||
if (mTopAppCache.get(jobStatus.getSourceUid()) || isTopStartedJobLocked(jobStatus)) {
|
||||
return Math.max(mEJLimitsMs[ACTIVE_INDEX] / 2,
|
||||
getTimeUntilEJQuotaConsumedLocked(
|
||||
@@ -929,9 +945,11 @@ public final class QuotaController extends StateController {
|
||||
|
||||
final long minSurplus;
|
||||
if (priority <= JobInfo.PRIORITY_MIN) {
|
||||
minSurplus = (long) (mAllowedTimePerPeriodMs * mAllowedTimeSurplusPriorityMin);
|
||||
minSurplus = (long)
|
||||
(mAllowedTimePerPeriodMs[standbyBucket] * mAllowedTimeSurplusPriorityMin);
|
||||
} else if (priority <= JobInfo.PRIORITY_LOW) {
|
||||
minSurplus = (long) (mAllowedTimePerPeriodMs * mAllowedTimeSurplusPriorityLow);
|
||||
minSurplus = (long)
|
||||
(mAllowedTimePerPeriodMs[standbyBucket] * mAllowedTimeSurplusPriorityLow);
|
||||
} else {
|
||||
minSurplus = 0;
|
||||
}
|
||||
@@ -989,7 +1007,7 @@ public final class QuotaController extends StateController {
|
||||
}
|
||||
|
||||
private long getRemainingExecutionTimeLocked(@NonNull ExecutionStats stats) {
|
||||
return Math.min(mAllowedTimePerPeriodMs - stats.executionTimeInWindowMs,
|
||||
return Math.min(stats.allowedTimePerPeriodMs - stats.executionTimeInWindowMs,
|
||||
mMaxExecutionTimeMs - stats.executionTimeInMaxPeriodMs);
|
||||
}
|
||||
|
||||
@@ -1068,15 +1086,15 @@ public final class QuotaController extends StateController {
|
||||
if (sessions == null || sessions.size() == 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) {
|
||||
if (stats.windowSizeMs == mAllowedTimePerPeriodMs[standbyBucket]) {
|
||||
return mMaxExecutionTimeMs;
|
||||
}
|
||||
return mAllowedTimePerPeriodMs;
|
||||
return mAllowedTimePerPeriodMs[standbyBucket];
|
||||
}
|
||||
|
||||
final long startWindowElapsed = nowElapsed - stats.windowSizeMs;
|
||||
final long startMaxElapsed = nowElapsed - MAX_PERIOD_MS;
|
||||
final long allowedTimePerPeriodMs = getAllowedTimePerPeriodMs(jobPriority);
|
||||
final long allowedTimePerPeriodMs = getAllowedTimePerPeriodMs(standbyBucket, jobPriority);
|
||||
final long allowedTimeRemainingMs = allowedTimePerPeriodMs - stats.executionTimeInWindowMs;
|
||||
final long maxExecutionTimeRemainingMs =
|
||||
mMaxExecutionTimeMs - stats.executionTimeInMaxPeriodMs;
|
||||
@@ -1087,7 +1105,7 @@ public final class QuotaController extends StateController {
|
||||
|
||||
// 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) {
|
||||
if (stats.windowSizeMs == mAllowedTimePerPeriodMs[standbyBucket]) {
|
||||
return calculateTimeUntilQuotaConsumedLocked(
|
||||
sessions, startMaxElapsed, maxExecutionTimeRemainingMs);
|
||||
}
|
||||
@@ -1103,14 +1121,19 @@ public final class QuotaController extends StateController {
|
||||
sessions, startWindowElapsed, allowedTimeRemainingMs));
|
||||
}
|
||||
|
||||
private long getAllowedTimePerPeriodMs(@JobInfo.Priority int jobPriority) {
|
||||
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) (mAllowedTimePerPeriodMs * (1 - mAllowedTimeSurplusPriorityMin));
|
||||
return (long) (initialAllowedTime * (1 - mAllowedTimeSurplusPriorityMin));
|
||||
}
|
||||
if (jobPriority <= JobInfo.PRIORITY_LOW) {
|
||||
return (long) (mAllowedTimePerPeriodMs * (1 - mAllowedTimeSurplusPriorityLow));
|
||||
return (long) (initialAllowedTime * (1 - mAllowedTimeSurplusPriorityLow));
|
||||
}
|
||||
return mAllowedTimePerPeriodMs;
|
||||
return initialAllowedTime;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1237,16 +1260,19 @@ public final class QuotaController extends StateController {
|
||||
appStats[standbyBucket] = stats;
|
||||
}
|
||||
if (refreshStatsIfOld) {
|
||||
final long bucketAllowedTimeMs = mAllowedTimePerPeriodMs[standbyBucket];
|
||||
final long bucketWindowSizeMs = mBucketPeriodsMs[standbyBucket];
|
||||
final int jobCountLimit = mMaxBucketJobCounts[standbyBucket];
|
||||
final int sessionCountLimit = mMaxBucketSessionCounts[standbyBucket];
|
||||
Timer timer = mPkgTimers.get(userId, packageName);
|
||||
if ((timer != null && timer.isActive())
|
||||
|| stats.expirationTimeElapsed <= sElapsedRealtimeClock.millis()
|
||||
|| stats.allowedTimePerPeriodMs != bucketAllowedTimeMs
|
||||
|| stats.windowSizeMs != bucketWindowSizeMs
|
||||
|| stats.jobCountLimit != jobCountLimit
|
||||
|| stats.sessionCountLimit != sessionCountLimit) {
|
||||
// The stats are no longer valid.
|
||||
stats.allowedTimePerPeriodMs = bucketAllowedTimeMs;
|
||||
stats.windowSizeMs = bucketWindowSizeMs;
|
||||
stats.jobCountLimit = jobCountLimit;
|
||||
stats.sessionCountLimit = sessionCountLimit;
|
||||
@@ -1272,8 +1298,11 @@ public final class QuotaController extends StateController {
|
||||
} else {
|
||||
stats.inQuotaTimeElapsed = 0;
|
||||
}
|
||||
final long allowedTimeMinMs = getAllowedTimePerPeriodMs(JobInfo.PRIORITY_MIN);
|
||||
final long allowedTimeLowMs = getAllowedTimePerPeriodMs(JobInfo.PRIORITY_LOW);
|
||||
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);
|
||||
final long nowElapsed = sElapsedRealtimeClock.millis();
|
||||
@@ -1287,9 +1316,9 @@ public final class QuotaController extends StateController {
|
||||
// If the timer is active, the value will be stale at the next method call, so
|
||||
// invalidate now.
|
||||
stats.expirationTimeElapsed = nowElapsed;
|
||||
if (stats.executionTimeInWindowMs >= mAllowedTimeIntoQuotaMs) {
|
||||
if (stats.executionTimeInWindowMs >= allowedTimeIntoQuotaMs) {
|
||||
stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed,
|
||||
nowElapsed - mAllowedTimeIntoQuotaMs + stats.windowSizeMs);
|
||||
nowElapsed - allowedTimeIntoQuotaMs + stats.windowSizeMs);
|
||||
}
|
||||
if (stats.executionTimeInWindowMs >= allowedTimeLowMs) {
|
||||
stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed,
|
||||
@@ -1346,9 +1375,9 @@ public final class QuotaController extends StateController {
|
||||
|
||||
stats.executionTimeInWindowMs += session.endTimeElapsed - start;
|
||||
stats.bgJobCountInWindow += session.bgJobCount;
|
||||
if (stats.executionTimeInWindowMs >= mAllowedTimeIntoQuotaMs) {
|
||||
if (stats.executionTimeInWindowMs >= allowedTimeIntoQuotaMs) {
|
||||
stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed,
|
||||
start + stats.executionTimeInWindowMs - mAllowedTimeIntoQuotaMs
|
||||
start + stats.executionTimeInWindowMs - allowedTimeIntoQuotaMs
|
||||
+ stats.windowSizeMs);
|
||||
}
|
||||
if (stats.executionTimeInWindowMs >= allowedTimeLowMs) {
|
||||
@@ -1697,7 +1726,7 @@ public final class QuotaController extends StateController {
|
||||
if (js.setQuotaConstraintSatisfied(nowElapsed, true)) {
|
||||
changedJobs.add(js);
|
||||
}
|
||||
} else if (realStandbyBucket != ACTIVE_INDEX
|
||||
} else if (realStandbyBucket != EXEMPTED_INDEX && realStandbyBucket != ACTIVE_INDEX
|
||||
&& realStandbyBucket == js.getEffectiveStandbyBucket()
|
||||
&& js.getEffectivePriority() >= JobInfo.PRIORITY_DEFAULT) {
|
||||
// An app in the ACTIVE bucket may be out of quota while the job could be in quota
|
||||
@@ -1842,7 +1871,8 @@ public final class QuotaController extends StateController {
|
||||
}
|
||||
}
|
||||
final boolean inRegularQuota =
|
||||
stats.executionTimeInWindowMs < getAllowedTimePerPeriodMs(minPriority)
|
||||
stats.executionTimeInWindowMs
|
||||
< getAllowedTimePerPeriodMs(standbyBucket, minPriority)
|
||||
&& stats.executionTimeInMaxPeriodMs < mMaxExecutionTimeMs
|
||||
&& isUnderJobCountQuota
|
||||
&& isUnderTimingSessionCountQuota;
|
||||
@@ -2921,9 +2951,29 @@ public final class QuotaController extends StateController {
|
||||
/** Prefix to use with all constant keys in order to "sub-namespace" the keys. */
|
||||
private static final String QC_CONSTANT_PREFIX = "qc_";
|
||||
|
||||
/**
|
||||
* Previously used keys:
|
||||
* * allowed_time_per_period_ms -- No longer used after splitting by bucket
|
||||
*/
|
||||
|
||||
@VisibleForTesting
|
||||
static final String KEY_ALLOWED_TIME_PER_PERIOD_MS =
|
||||
QC_CONSTANT_PREFIX + "allowed_time_per_period_ms";
|
||||
static final String KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS =
|
||||
QC_CONSTANT_PREFIX + "allowed_time_per_period_exempted_ms";
|
||||
@VisibleForTesting
|
||||
static final String KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS =
|
||||
QC_CONSTANT_PREFIX + "allowed_time_per_period_active_ms";
|
||||
@VisibleForTesting
|
||||
static final String KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS =
|
||||
QC_CONSTANT_PREFIX + "allowed_time_per_period_working_ms";
|
||||
@VisibleForTesting
|
||||
static final String KEY_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS =
|
||||
QC_CONSTANT_PREFIX + "allowed_time_per_period_frequent_ms";
|
||||
@VisibleForTesting
|
||||
static final String KEY_ALLOWED_TIME_PER_PERIOD_RARE_MS =
|
||||
QC_CONSTANT_PREFIX + "allowed_time_per_period_rare_ms";
|
||||
@VisibleForTesting
|
||||
static final String KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS =
|
||||
QC_CONSTANT_PREFIX + "allowed_time_per_period_restricted_ms";
|
||||
@VisibleForTesting
|
||||
static final String KEY_IN_QUOTA_BUFFER_MS =
|
||||
QC_CONSTANT_PREFIX + "in_quota_buffer_ms";
|
||||
@@ -2934,6 +2984,9 @@ public final class QuotaController extends StateController {
|
||||
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
|
||||
static final String KEY_WINDOW_SIZE_ACTIVE_MS =
|
||||
QC_CONSTANT_PREFIX + "window_size_active_ms";
|
||||
@VisibleForTesting
|
||||
@@ -2952,6 +3005,9 @@ public final class QuotaController extends StateController {
|
||||
static final String KEY_MAX_EXECUTION_TIME_MS =
|
||||
QC_CONSTANT_PREFIX + "max_execution_time_ms";
|
||||
@VisibleForTesting
|
||||
static final String KEY_MAX_JOB_COUNT_EXEMPTED =
|
||||
QC_CONSTANT_PREFIX + "max_job_count_exempted";
|
||||
@VisibleForTesting
|
||||
static final String KEY_MAX_JOB_COUNT_ACTIVE =
|
||||
QC_CONSTANT_PREFIX + "max_job_count_active";
|
||||
@VisibleForTesting
|
||||
@@ -2973,6 +3029,9 @@ public final class QuotaController extends StateController {
|
||||
static final String KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW =
|
||||
QC_CONSTANT_PREFIX + "max_job_count_per_rate_limiting_window";
|
||||
@VisibleForTesting
|
||||
static final String KEY_MAX_SESSION_COUNT_EXEMPTED =
|
||||
QC_CONSTANT_PREFIX + "max_session_count_exempted";
|
||||
@VisibleForTesting
|
||||
static final String KEY_MAX_SESSION_COUNT_ACTIVE =
|
||||
QC_CONSTANT_PREFIX + "max_session_count_active";
|
||||
@VisibleForTesting
|
||||
@@ -2997,6 +3056,9 @@ public final class QuotaController extends StateController {
|
||||
static final String KEY_MIN_QUOTA_CHECK_DELAY_MS =
|
||||
QC_CONSTANT_PREFIX + "min_quota_check_delay_ms";
|
||||
@VisibleForTesting
|
||||
static final String KEY_EJ_LIMIT_EXEMPTED_MS =
|
||||
QC_CONSTANT_PREFIX + "ej_limit_exempted_ms";
|
||||
@VisibleForTesting
|
||||
static final String KEY_EJ_LIMIT_ACTIVE_MS =
|
||||
QC_CONSTANT_PREFIX + "ej_limit_active_ms";
|
||||
@VisibleForTesting
|
||||
@@ -3039,14 +3101,26 @@ public final class QuotaController extends StateController {
|
||||
static final String KEY_EJ_GRACE_PERIOD_TOP_APP_MS =
|
||||
QC_CONSTANT_PREFIX + "ej_grace_period_top_app_ms";
|
||||
|
||||
private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_MS =
|
||||
private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS =
|
||||
10 * 60 * 1000L; // 10 minutes
|
||||
private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS =
|
||||
10 * 60 * 1000L; // 10 minutes
|
||||
private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_WORKING_MS =
|
||||
10 * 60 * 1000L; // 10 minutes
|
||||
private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS =
|
||||
10 * 60 * 1000L; // 10 minutes
|
||||
private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_RARE_MS =
|
||||
10 * 60 * 1000L; // 10 minutes
|
||||
private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS =
|
||||
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 =
|
||||
DEFAULT_ALLOWED_TIME_PER_PERIOD_MS; // ACTIVE apps can run jobs at any time
|
||||
DEFAULT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS; // ACTIVE apps can run jobs at any time
|
||||
private static final long DEFAULT_WINDOW_SIZE_WORKING_MS =
|
||||
2 * 60 * 60 * 1000L; // 2 hours
|
||||
private static final long DEFAULT_WINDOW_SIZE_FREQUENT_MS =
|
||||
@@ -3060,8 +3134,9 @@ public final class QuotaController extends StateController {
|
||||
private static final long DEFAULT_RATE_LIMITING_WINDOW_MS =
|
||||
MINUTE_IN_MILLIS;
|
||||
private static final int DEFAULT_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW = 20;
|
||||
private static final int DEFAULT_MAX_JOB_COUNT_ACTIVE =
|
||||
private static final int DEFAULT_MAX_JOB_COUNT_EXEMPTED =
|
||||
75; // 75/window = 450/hr = 1/session
|
||||
private static final int DEFAULT_MAX_JOB_COUNT_ACTIVE = DEFAULT_MAX_JOB_COUNT_EXEMPTED;
|
||||
private static final int DEFAULT_MAX_JOB_COUNT_WORKING = // 120/window = 60/hr = 12/session
|
||||
(int) (60.0 * DEFAULT_WINDOW_SIZE_WORKING_MS / HOUR_IN_MILLIS);
|
||||
private static final int DEFAULT_MAX_JOB_COUNT_FREQUENT = // 200/window = 25/hr = 25/session
|
||||
@@ -3069,8 +3144,10 @@ public final class QuotaController extends StateController {
|
||||
private static final int DEFAULT_MAX_JOB_COUNT_RARE = // 48/window = 2/hr = 16/session
|
||||
(int) (2.0 * DEFAULT_WINDOW_SIZE_RARE_MS / HOUR_IN_MILLIS);
|
||||
private static final int DEFAULT_MAX_JOB_COUNT_RESTRICTED = 10;
|
||||
private static final int DEFAULT_MAX_SESSION_COUNT_ACTIVE =
|
||||
private static final int DEFAULT_MAX_SESSION_COUNT_EXEMPTED =
|
||||
75; // 450/hr
|
||||
private static final int DEFAULT_MAX_SESSION_COUNT_ACTIVE =
|
||||
DEFAULT_MAX_SESSION_COUNT_EXEMPTED;
|
||||
private static final int DEFAULT_MAX_SESSION_COUNT_WORKING =
|
||||
10; // 5/hr
|
||||
private static final int DEFAULT_MAX_SESSION_COUNT_FREQUENT =
|
||||
@@ -3081,6 +3158,7 @@ public final class QuotaController extends StateController {
|
||||
private static final int DEFAULT_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW = 20;
|
||||
private static final long DEFAULT_TIMING_SESSION_COALESCING_DURATION_MS = 5000; // 5 seconds
|
||||
private static final long DEFAULT_MIN_QUOTA_CHECK_DELAY_MS = MINUTE_IN_MILLIS;
|
||||
private static final long DEFAULT_EJ_LIMIT_EXEMPTED_MS = 45 * MINUTE_IN_MILLIS;
|
||||
private static final long DEFAULT_EJ_LIMIT_ACTIVE_MS = 30 * MINUTE_IN_MILLIS;
|
||||
private static final long DEFAULT_EJ_LIMIT_WORKING_MS = DEFAULT_EJ_LIMIT_ACTIVE_MS;
|
||||
private static final long DEFAULT_EJ_LIMIT_FREQUENT_MS = 10 * MINUTE_IN_MILLIS;
|
||||
@@ -3096,8 +3174,39 @@ public final class QuotaController extends StateController {
|
||||
private static final long DEFAULT_EJ_GRACE_PERIOD_TEMP_ALLOWLIST_MS = 3 * MINUTE_IN_MILLIS;
|
||||
private static final long DEFAULT_EJ_GRACE_PERIOD_TOP_APP_MS = 1 * MINUTE_IN_MILLIS;
|
||||
|
||||
/** How much time each app will have to run jobs within their standby bucket window. */
|
||||
public long ALLOWED_TIME_PER_PERIOD_MS = DEFAULT_ALLOWED_TIME_PER_PERIOD_MS;
|
||||
/**
|
||||
* How much time each app in the exempted bucket will have to run jobs within their standby
|
||||
* bucket window.
|
||||
*/
|
||||
public long ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS =
|
||||
DEFAULT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
|
||||
/**
|
||||
* How much time each app in the active bucket will have to run jobs within their standby
|
||||
* bucket window.
|
||||
*/
|
||||
public long ALLOWED_TIME_PER_PERIOD_ACTIVE_MS = DEFAULT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
|
||||
/**
|
||||
* How much time each app in the working set bucket will have to run jobs within their
|
||||
* standby bucket window.
|
||||
*/
|
||||
public long ALLOWED_TIME_PER_PERIOD_WORKING_MS = DEFAULT_ALLOWED_TIME_PER_PERIOD_WORKING_MS;
|
||||
/**
|
||||
* How much time each app in the frequent bucket will have to run jobs within their standby
|
||||
* bucket window.
|
||||
*/
|
||||
public long ALLOWED_TIME_PER_PERIOD_FREQUENT_MS =
|
||||
DEFAULT_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS;
|
||||
/**
|
||||
* How much time each app in the rare bucket will have to run jobs within their standby
|
||||
* bucket window.
|
||||
*/
|
||||
public long ALLOWED_TIME_PER_PERIOD_RARE_MS = DEFAULT_ALLOWED_TIME_PER_PERIOD_RARE_MS;
|
||||
/**
|
||||
* How much time each app in the restricted bucket will have to run jobs within their
|
||||
* standby bucket window.
|
||||
*/
|
||||
public long ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS =
|
||||
DEFAULT_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS;
|
||||
|
||||
/**
|
||||
* How much time the package should have before transitioning from out-of-quota to in-quota.
|
||||
@@ -3106,7 +3215,7 @@ public final class QuotaController extends StateController {
|
||||
public long IN_QUOTA_BUFFER_MS = DEFAULT_IN_QUOTA_BUFFER_MS;
|
||||
|
||||
/**
|
||||
* The percentage of {@link #ALLOWED_TIME_PER_PERIOD_MS} that should not be used by
|
||||
* 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.
|
||||
@@ -3114,7 +3223,7 @@ public final class QuotaController extends StateController {
|
||||
public float ALLOWED_TIME_SURPLUS_PRIORITY_LOW = DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_LOW;
|
||||
|
||||
/**
|
||||
* The percentage of {@link #ALLOWED_TIME_PER_PERIOD_MS} that should not be used by
|
||||
* 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.
|
||||
@@ -3123,35 +3232,42 @@ public final class QuotaController extends StateController {
|
||||
|
||||
/**
|
||||
* The quota window size of the particular standby bucket. Apps in this standby bucket are
|
||||
* expected to run only {@link #ALLOWED_TIME_PER_PERIOD_MS} within the past
|
||||
* expected to run only {@link #ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS} within the past
|
||||
* WINDOW_SIZE_MS.
|
||||
*/
|
||||
public long WINDOW_SIZE_EXEMPTED_MS = DEFAULT_WINDOW_SIZE_EXEMPTED_MS;
|
||||
|
||||
/**
|
||||
* The quota window size of the particular standby bucket. Apps in this standby bucket are
|
||||
* expected to run only {@link #ALLOWED_TIME_PER_PERIOD_ACTIVE_MS} within the past
|
||||
* WINDOW_SIZE_MS.
|
||||
*/
|
||||
public long WINDOW_SIZE_ACTIVE_MS = DEFAULT_WINDOW_SIZE_ACTIVE_MS;
|
||||
|
||||
/**
|
||||
* The quota window size of the particular standby bucket. Apps in this standby bucket are
|
||||
* expected to run only {@link #ALLOWED_TIME_PER_PERIOD_MS} within the past
|
||||
* expected to run only {@link #ALLOWED_TIME_PER_PERIOD_WORKING_MS} within the past
|
||||
* WINDOW_SIZE_MS.
|
||||
*/
|
||||
public long WINDOW_SIZE_WORKING_MS = DEFAULT_WINDOW_SIZE_WORKING_MS;
|
||||
|
||||
/**
|
||||
* The quota window size of the particular standby bucket. Apps in this standby bucket are
|
||||
* expected to run only {@link #ALLOWED_TIME_PER_PERIOD_MS} within the past
|
||||
* expected to run only {@link #ALLOWED_TIME_PER_PERIOD_FREQUENT_MS} within the past
|
||||
* WINDOW_SIZE_MS.
|
||||
*/
|
||||
public long WINDOW_SIZE_FREQUENT_MS = DEFAULT_WINDOW_SIZE_FREQUENT_MS;
|
||||
|
||||
/**
|
||||
* The quota window size of the particular standby bucket. Apps in this standby bucket are
|
||||
* expected to run only {@link #ALLOWED_TIME_PER_PERIOD_MS} within the past
|
||||
* expected to run only {@link #ALLOWED_TIME_PER_PERIOD_RARE_MS} within the past
|
||||
* WINDOW_SIZE_MS.
|
||||
*/
|
||||
public long WINDOW_SIZE_RARE_MS = DEFAULT_WINDOW_SIZE_RARE_MS;
|
||||
|
||||
/**
|
||||
* The quota window size of the particular standby bucket. Apps in this standby bucket are
|
||||
* expected to run only {@link #ALLOWED_TIME_PER_PERIOD_MS} within the past
|
||||
* expected to run only {@link #ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS} within the past
|
||||
* WINDOW_SIZE_MS.
|
||||
*/
|
||||
public long WINDOW_SIZE_RESTRICTED_MS = DEFAULT_WINDOW_SIZE_RESTRICTED_MS;
|
||||
@@ -3161,6 +3277,12 @@ public final class QuotaController extends StateController {
|
||||
*/
|
||||
public long MAX_EXECUTION_TIME_MS = DEFAULT_MAX_EXECUTION_TIME_MS;
|
||||
|
||||
/**
|
||||
* The maximum number of jobs an app can run within this particular standby bucket's
|
||||
* window size.
|
||||
*/
|
||||
public int MAX_JOB_COUNT_EXEMPTED = DEFAULT_MAX_JOB_COUNT_EXEMPTED;
|
||||
|
||||
/**
|
||||
* The maximum number of jobs an app can run within this particular standby bucket's
|
||||
* window size.
|
||||
@@ -3200,6 +3322,12 @@ public final class QuotaController extends StateController {
|
||||
public int MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW =
|
||||
DEFAULT_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW;
|
||||
|
||||
/**
|
||||
* The maximum number of {@link TimingSession TimingSessions} an app can run within this
|
||||
* particular standby bucket's window size.
|
||||
*/
|
||||
public int MAX_SESSION_COUNT_EXEMPTED = DEFAULT_MAX_SESSION_COUNT_EXEMPTED;
|
||||
|
||||
/**
|
||||
* The maximum number of {@link TimingSession TimingSessions} an app can run within this
|
||||
* particular standby bucket's window size.
|
||||
@@ -3232,7 +3360,7 @@ public final class QuotaController extends StateController {
|
||||
|
||||
/**
|
||||
* The maximum number of {@link TimingSession TimingSessions} that can run within the past
|
||||
* {@link #ALLOWED_TIME_PER_PERIOD_MS}.
|
||||
* {@link #RATE_LIMITING_WINDOW_MS}.
|
||||
*/
|
||||
public int MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW =
|
||||
DEFAULT_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW;
|
||||
@@ -3270,6 +3398,13 @@ public final class QuotaController extends StateController {
|
||||
/** The minimum value that {@link #RATE_LIMITING_WINDOW_MS} can have. */
|
||||
private static final long MIN_RATE_LIMITING_WINDOW_MS = 30 * SECOND_IN_MILLIS;
|
||||
|
||||
/**
|
||||
* The total expedited job session limit of the particular standby bucket. Apps in this
|
||||
* standby bucket can only have expedited job sessions totalling EJ_LIMIT (without factoring
|
||||
* in any rewards or free EJs).
|
||||
*/
|
||||
public long EJ_LIMIT_EXEMPTED_MS = DEFAULT_EJ_LIMIT_EXEMPTED_MS;
|
||||
|
||||
/**
|
||||
* The total expedited job session limit of the particular standby bucket. Apps in this
|
||||
* standby bucket can only have expedited job sessions totalling EJ_LIMIT (without factoring
|
||||
@@ -3358,7 +3493,12 @@ public final class QuotaController extends StateController {
|
||||
public void processConstantLocked(@NonNull DeviceConfig.Properties properties,
|
||||
@NonNull String key) {
|
||||
switch (key) {
|
||||
case KEY_ALLOWED_TIME_PER_PERIOD_MS:
|
||||
case KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS:
|
||||
case KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS:
|
||||
case KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS:
|
||||
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:
|
||||
@@ -3388,6 +3528,15 @@ public final class QuotaController extends StateController {
|
||||
updateEJLimitConstantsLocked();
|
||||
break;
|
||||
|
||||
case KEY_MAX_JOB_COUNT_EXEMPTED:
|
||||
MAX_JOB_COUNT_EXEMPTED = properties.getInt(key, DEFAULT_MAX_JOB_COUNT_EXEMPTED);
|
||||
int newExemptedMaxJobCount =
|
||||
Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_EXEMPTED);
|
||||
if (mMaxBucketJobCounts[EXEMPTED_INDEX] != newExemptedMaxJobCount) {
|
||||
mMaxBucketJobCounts[EXEMPTED_INDEX] = newExemptedMaxJobCount;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
break;
|
||||
case KEY_MAX_JOB_COUNT_ACTIVE:
|
||||
MAX_JOB_COUNT_ACTIVE = properties.getInt(key, DEFAULT_MAX_JOB_COUNT_ACTIVE);
|
||||
int newActiveMaxJobCount = Math.max(MIN_BUCKET_JOB_COUNT, MAX_JOB_COUNT_ACTIVE);
|
||||
@@ -3432,6 +3581,16 @@ public final class QuotaController extends StateController {
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
break;
|
||||
case KEY_MAX_SESSION_COUNT_EXEMPTED:
|
||||
MAX_SESSION_COUNT_EXEMPTED =
|
||||
properties.getInt(key, DEFAULT_MAX_SESSION_COUNT_EXEMPTED);
|
||||
int newExemptedMaxSessionCount =
|
||||
Math.max(MIN_BUCKET_SESSION_COUNT, MAX_SESSION_COUNT_EXEMPTED);
|
||||
if (mMaxBucketSessionCounts[EXEMPTED_INDEX] != newExemptedMaxSessionCount) {
|
||||
mMaxBucketSessionCounts[EXEMPTED_INDEX] = newExemptedMaxSessionCount;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
break;
|
||||
case KEY_MAX_SESSION_COUNT_ACTIVE:
|
||||
MAX_SESSION_COUNT_ACTIVE =
|
||||
properties.getInt(key, DEFAULT_MAX_SESSION_COUNT_ACTIVE);
|
||||
@@ -3579,15 +3738,34 @@ public final class QuotaController extends StateController {
|
||||
// Query the values as an atomic set.
|
||||
final DeviceConfig.Properties properties = DeviceConfig.getProperties(
|
||||
DeviceConfig.NAMESPACE_JOB_SCHEDULER,
|
||||
KEY_ALLOWED_TIME_PER_PERIOD_MS, KEY_IN_QUOTA_BUFFER_MS,
|
||||
KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS, KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS,
|
||||
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_ACTIVE_MS,
|
||||
KEY_MAX_EXECUTION_TIME_MS,
|
||||
KEY_WINDOW_SIZE_EXEMPTED_MS, KEY_WINDOW_SIZE_ACTIVE_MS,
|
||||
KEY_WINDOW_SIZE_WORKING_MS,
|
||||
KEY_WINDOW_SIZE_FREQUENT_MS, KEY_WINDOW_SIZE_RARE_MS,
|
||||
KEY_WINDOW_SIZE_RESTRICTED_MS);
|
||||
ALLOWED_TIME_PER_PERIOD_MS =
|
||||
properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_MS,
|
||||
DEFAULT_ALLOWED_TIME_PER_PERIOD_MS);
|
||||
ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS =
|
||||
properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS,
|
||||
DEFAULT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS);
|
||||
ALLOWED_TIME_PER_PERIOD_ACTIVE_MS =
|
||||
properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS,
|
||||
DEFAULT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS);
|
||||
ALLOWED_TIME_PER_PERIOD_WORKING_MS =
|
||||
properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS,
|
||||
DEFAULT_ALLOWED_TIME_PER_PERIOD_WORKING_MS);
|
||||
ALLOWED_TIME_PER_PERIOD_FREQUENT_MS =
|
||||
properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS,
|
||||
DEFAULT_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS);
|
||||
ALLOWED_TIME_PER_PERIOD_RARE_MS =
|
||||
properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_RARE_MS,
|
||||
DEFAULT_ALLOWED_TIME_PER_PERIOD_RARE_MS);
|
||||
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);
|
||||
@@ -3598,6 +3776,8 @@ public final class QuotaController extends StateController {
|
||||
DEFAULT_IN_QUOTA_BUFFER_MS);
|
||||
MAX_EXECUTION_TIME_MS = properties.getLong(KEY_MAX_EXECUTION_TIME_MS,
|
||||
DEFAULT_MAX_EXECUTION_TIME_MS);
|
||||
WINDOW_SIZE_EXEMPTED_MS = properties.getLong(KEY_WINDOW_SIZE_EXEMPTED_MS,
|
||||
DEFAULT_WINDOW_SIZE_EXEMPTED_MS);
|
||||
WINDOW_SIZE_ACTIVE_MS = properties.getLong(KEY_WINDOW_SIZE_ACTIVE_MS,
|
||||
DEFAULT_WINDOW_SIZE_ACTIVE_MS);
|
||||
WINDOW_SIZE_WORKING_MS =
|
||||
@@ -3618,20 +3798,55 @@ public final class QuotaController extends StateController {
|
||||
mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
long newAllowedTimeMs = Math.min(mMaxExecutionTimeMs,
|
||||
Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_MS));
|
||||
if (mAllowedTimePerPeriodMs != newAllowedTimeMs) {
|
||||
mAllowedTimePerPeriodMs = newAllowedTimeMs;
|
||||
mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs;
|
||||
long minAllowedTimeMs = Long.MAX_VALUE;
|
||||
long newAllowedTimeExemptedMs = Math.min(mMaxExecutionTimeMs,
|
||||
Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS));
|
||||
minAllowedTimeMs = Math.min(minAllowedTimeMs, newAllowedTimeExemptedMs);
|
||||
if (mAllowedTimePerPeriodMs[EXEMPTED_INDEX] != newAllowedTimeExemptedMs) {
|
||||
mAllowedTimePerPeriodMs[EXEMPTED_INDEX] = newAllowedTimeExemptedMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
long newAllowedTimeActiveMs = Math.min(mMaxExecutionTimeMs,
|
||||
Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_ACTIVE_MS));
|
||||
minAllowedTimeMs = Math.min(minAllowedTimeMs, newAllowedTimeActiveMs);
|
||||
if (mAllowedTimePerPeriodMs[ACTIVE_INDEX] != newAllowedTimeActiveMs) {
|
||||
mAllowedTimePerPeriodMs[ACTIVE_INDEX] = newAllowedTimeActiveMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
long newAllowedTimeWorkingMs = Math.min(mMaxExecutionTimeMs,
|
||||
Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_WORKING_MS));
|
||||
minAllowedTimeMs = Math.min(minAllowedTimeMs, newAllowedTimeWorkingMs);
|
||||
if (mAllowedTimePerPeriodMs[WORKING_INDEX] != newAllowedTimeWorkingMs) {
|
||||
mAllowedTimePerPeriodMs[WORKING_INDEX] = newAllowedTimeWorkingMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
long newAllowedTimeFrequentMs = Math.min(mMaxExecutionTimeMs,
|
||||
Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_FREQUENT_MS));
|
||||
minAllowedTimeMs = Math.min(minAllowedTimeMs, newAllowedTimeFrequentMs);
|
||||
if (mAllowedTimePerPeriodMs[FREQUENT_INDEX] != newAllowedTimeFrequentMs) {
|
||||
mAllowedTimePerPeriodMs[FREQUENT_INDEX] = newAllowedTimeFrequentMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
long newAllowedTimeRareMs = Math.min(mMaxExecutionTimeMs,
|
||||
Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_RARE_MS));
|
||||
minAllowedTimeMs = Math.min(minAllowedTimeMs, newAllowedTimeRareMs);
|
||||
if (mAllowedTimePerPeriodMs[RARE_INDEX] != newAllowedTimeRareMs) {
|
||||
mAllowedTimePerPeriodMs[RARE_INDEX] = newAllowedTimeRareMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
long newAllowedTimeRestrictedMs = Math.min(mMaxExecutionTimeMs,
|
||||
Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS));
|
||||
minAllowedTimeMs = Math.min(minAllowedTimeMs, newAllowedTimeRestrictedMs);
|
||||
if (mAllowedTimePerPeriodMs[RESTRICTED_INDEX] != newAllowedTimeRestrictedMs) {
|
||||
mAllowedTimePerPeriodMs[RESTRICTED_INDEX] = newAllowedTimeRestrictedMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
// Make sure quota buffer is non-negative, not greater than allowed time per period,
|
||||
// and no more than 5 minutes.
|
||||
long newQuotaBufferMs = Math.max(0, Math.min(mAllowedTimePerPeriodMs,
|
||||
long newQuotaBufferMs = Math.max(0, Math.min(minAllowedTimeMs,
|
||||
Math.min(5 * MINUTE_IN_MILLIS, IN_QUOTA_BUFFER_MS)));
|
||||
if (mQuotaBufferMs != newQuotaBufferMs) {
|
||||
mQuotaBufferMs = newQuotaBufferMs;
|
||||
mAllowedTimeIntoQuotaMs = mAllowedTimePerPeriodMs - mQuotaBufferMs;
|
||||
mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
@@ -3652,32 +3867,38 @@ public final class QuotaController extends StateController {
|
||||
mAllowedTimeSurplusPriorityMin = newAllowedTimeSurplusPriorityMin;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
long newActivePeriodMs = Math.max(mAllowedTimePerPeriodMs,
|
||||
long newExemptedPeriodMs = Math.max(mAllowedTimePerPeriodMs[EXEMPTED_INDEX],
|
||||
Math.min(MAX_PERIOD_MS, WINDOW_SIZE_EXEMPTED_MS));
|
||||
if (mBucketPeriodsMs[EXEMPTED_INDEX] != newExemptedPeriodMs) {
|
||||
mBucketPeriodsMs[EXEMPTED_INDEX] = newExemptedPeriodMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
long newActivePeriodMs = Math.max(mAllowedTimePerPeriodMs[ACTIVE_INDEX],
|
||||
Math.min(MAX_PERIOD_MS, WINDOW_SIZE_ACTIVE_MS));
|
||||
if (mBucketPeriodsMs[ACTIVE_INDEX] != newActivePeriodMs) {
|
||||
mBucketPeriodsMs[ACTIVE_INDEX] = newActivePeriodMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
long newWorkingPeriodMs = Math.max(mAllowedTimePerPeriodMs,
|
||||
long newWorkingPeriodMs = Math.max(mAllowedTimePerPeriodMs[WORKING_INDEX],
|
||||
Math.min(MAX_PERIOD_MS, WINDOW_SIZE_WORKING_MS));
|
||||
if (mBucketPeriodsMs[WORKING_INDEX] != newWorkingPeriodMs) {
|
||||
mBucketPeriodsMs[WORKING_INDEX] = newWorkingPeriodMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
long newFrequentPeriodMs = Math.max(mAllowedTimePerPeriodMs,
|
||||
long newFrequentPeriodMs = Math.max(mAllowedTimePerPeriodMs[FREQUENT_INDEX],
|
||||
Math.min(MAX_PERIOD_MS, WINDOW_SIZE_FREQUENT_MS));
|
||||
if (mBucketPeriodsMs[FREQUENT_INDEX] != newFrequentPeriodMs) {
|
||||
mBucketPeriodsMs[FREQUENT_INDEX] = newFrequentPeriodMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
long newRarePeriodMs = Math.max(mAllowedTimePerPeriodMs,
|
||||
long newRarePeriodMs = Math.max(mAllowedTimePerPeriodMs[RARE_INDEX],
|
||||
Math.min(MAX_PERIOD_MS, WINDOW_SIZE_RARE_MS));
|
||||
if (mBucketPeriodsMs[RARE_INDEX] != newRarePeriodMs) {
|
||||
mBucketPeriodsMs[RARE_INDEX] = newRarePeriodMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
// Fit in the range [allowed time (10 mins), 1 week].
|
||||
long newRestrictedPeriodMs = Math.max(mAllowedTimePerPeriodMs,
|
||||
long newRestrictedPeriodMs = Math.max(mAllowedTimePerPeriodMs[RESTRICTED_INDEX],
|
||||
Math.min(7 * 24 * 60 * MINUTE_IN_MILLIS, WINDOW_SIZE_RESTRICTED_MS));
|
||||
if (mBucketPeriodsMs[RESTRICTED_INDEX] != newRestrictedPeriodMs) {
|
||||
mBucketPeriodsMs[RESTRICTED_INDEX] = newRestrictedPeriodMs;
|
||||
@@ -3740,11 +3961,14 @@ public final class QuotaController extends StateController {
|
||||
// Query the values as an atomic set.
|
||||
final DeviceConfig.Properties properties = DeviceConfig.getProperties(
|
||||
DeviceConfig.NAMESPACE_JOB_SCHEDULER,
|
||||
KEY_EJ_LIMIT_EXEMPTED_MS,
|
||||
KEY_EJ_LIMIT_ACTIVE_MS, KEY_EJ_LIMIT_WORKING_MS,
|
||||
KEY_EJ_LIMIT_FREQUENT_MS, KEY_EJ_LIMIT_RARE_MS,
|
||||
KEY_EJ_LIMIT_RESTRICTED_MS, KEY_EJ_LIMIT_ADDITION_SPECIAL_MS,
|
||||
KEY_EJ_LIMIT_ADDITION_INSTALLER_MS,
|
||||
KEY_EJ_WINDOW_SIZE_MS);
|
||||
EJ_LIMIT_EXEMPTED_MS = properties.getLong(
|
||||
KEY_EJ_LIMIT_EXEMPTED_MS, DEFAULT_EJ_LIMIT_EXEMPTED_MS);
|
||||
EJ_LIMIT_ACTIVE_MS = properties.getLong(
|
||||
KEY_EJ_LIMIT_ACTIVE_MS, DEFAULT_EJ_LIMIT_ACTIVE_MS);
|
||||
EJ_LIMIT_WORKING_MS = properties.getLong(
|
||||
@@ -3770,8 +3994,15 @@ public final class QuotaController extends StateController {
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
// The limit must be in the range [15 minutes, window size].
|
||||
long newExemptLimitMs = Math.max(15 * MINUTE_IN_MILLIS,
|
||||
Math.min(newWindowSizeMs, EJ_LIMIT_EXEMPTED_MS));
|
||||
if (mEJLimitsMs[EXEMPTED_INDEX] != newExemptLimitMs) {
|
||||
mEJLimitsMs[EXEMPTED_INDEX] = newExemptLimitMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
}
|
||||
// The limit must be in the range [15 minutes, exempted limit].
|
||||
long newActiveLimitMs = Math.max(15 * MINUTE_IN_MILLIS,
|
||||
Math.min(newWindowSizeMs, EJ_LIMIT_ACTIVE_MS));
|
||||
Math.min(newExemptLimitMs, EJ_LIMIT_ACTIVE_MS));
|
||||
if (mEJLimitsMs[ACTIVE_INDEX] != newActiveLimitMs) {
|
||||
mEJLimitsMs[ACTIVE_INDEX] = newActiveLimitMs;
|
||||
mShouldReevaluateConstraints = true;
|
||||
@@ -3823,18 +4054,31 @@ public final class QuotaController extends StateController {
|
||||
pw.println();
|
||||
pw.println("QuotaController:");
|
||||
pw.increaseIndent();
|
||||
pw.print(KEY_ALLOWED_TIME_PER_PERIOD_MS, ALLOWED_TIME_PER_PERIOD_MS).println();
|
||||
pw.print(KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS, ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS)
|
||||
.println();
|
||||
pw.print(KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS, ALLOWED_TIME_PER_PERIOD_ACTIVE_MS)
|
||||
.println();
|
||||
pw.print(KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS, ALLOWED_TIME_PER_PERIOD_WORKING_MS)
|
||||
.println();
|
||||
pw.print(KEY_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS, ALLOWED_TIME_PER_PERIOD_FREQUENT_MS)
|
||||
.println();
|
||||
pw.print(KEY_ALLOWED_TIME_PER_PERIOD_RARE_MS, ALLOWED_TIME_PER_PERIOD_RARE_MS)
|
||||
.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();
|
||||
pw.print(KEY_WINDOW_SIZE_WORKING_MS, WINDOW_SIZE_WORKING_MS).println();
|
||||
pw.print(KEY_WINDOW_SIZE_FREQUENT_MS, WINDOW_SIZE_FREQUENT_MS).println();
|
||||
pw.print(KEY_WINDOW_SIZE_RARE_MS, WINDOW_SIZE_RARE_MS).println();
|
||||
pw.print(KEY_WINDOW_SIZE_RESTRICTED_MS, WINDOW_SIZE_RESTRICTED_MS).println();
|
||||
pw.print(KEY_MAX_EXECUTION_TIME_MS, MAX_EXECUTION_TIME_MS).println();
|
||||
pw.print(KEY_MAX_JOB_COUNT_EXEMPTED, MAX_JOB_COUNT_EXEMPTED).println();
|
||||
pw.print(KEY_MAX_JOB_COUNT_ACTIVE, MAX_JOB_COUNT_ACTIVE).println();
|
||||
pw.print(KEY_MAX_JOB_COUNT_WORKING, MAX_JOB_COUNT_WORKING).println();
|
||||
pw.print(KEY_MAX_JOB_COUNT_FREQUENT, MAX_JOB_COUNT_FREQUENT).println();
|
||||
@@ -3843,6 +4087,7 @@ public final class QuotaController extends StateController {
|
||||
pw.print(KEY_RATE_LIMITING_WINDOW_MS, RATE_LIMITING_WINDOW_MS).println();
|
||||
pw.print(KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW,
|
||||
MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW).println();
|
||||
pw.print(KEY_MAX_SESSION_COUNT_EXEMPTED, MAX_SESSION_COUNT_EXEMPTED).println();
|
||||
pw.print(KEY_MAX_SESSION_COUNT_ACTIVE, MAX_SESSION_COUNT_ACTIVE).println();
|
||||
pw.print(KEY_MAX_SESSION_COUNT_WORKING, MAX_SESSION_COUNT_WORKING).println();
|
||||
pw.print(KEY_MAX_SESSION_COUNT_FREQUENT, MAX_SESSION_COUNT_FREQUENT).println();
|
||||
@@ -3854,6 +4099,7 @@ public final class QuotaController extends StateController {
|
||||
TIMING_SESSION_COALESCING_DURATION_MS).println();
|
||||
pw.print(KEY_MIN_QUOTA_CHECK_DELAY_MS, MIN_QUOTA_CHECK_DELAY_MS).println();
|
||||
|
||||
pw.print(KEY_EJ_LIMIT_EXEMPTED_MS, EJ_LIMIT_EXEMPTED_MS).println();
|
||||
pw.print(KEY_EJ_LIMIT_ACTIVE_MS, EJ_LIMIT_ACTIVE_MS).println();
|
||||
pw.print(KEY_EJ_LIMIT_WORKING_MS, EJ_LIMIT_WORKING_MS).println();
|
||||
pw.print(KEY_EJ_LIMIT_FREQUENT_MS, EJ_LIMIT_FREQUENT_MS).println();
|
||||
@@ -3875,8 +4121,6 @@ public final class QuotaController extends StateController {
|
||||
|
||||
private void dump(ProtoOutputStream proto) {
|
||||
final long qcToken = proto.start(ConstantsProto.QUOTA_CONTROLLER);
|
||||
proto.write(ConstantsProto.QuotaController.ALLOWED_TIME_PER_PERIOD_MS,
|
||||
ALLOWED_TIME_PER_PERIOD_MS);
|
||||
proto.write(ConstantsProto.QuotaController.IN_QUOTA_BUFFER_MS, IN_QUOTA_BUFFER_MS);
|
||||
proto.write(ConstantsProto.QuotaController.ACTIVE_WINDOW_SIZE_MS,
|
||||
WINDOW_SIZE_ACTIVE_MS);
|
||||
@@ -3946,7 +4190,7 @@ public final class QuotaController extends StateController {
|
||||
//////////////////////// TESTING HELPERS /////////////////////////////
|
||||
|
||||
@VisibleForTesting
|
||||
long getAllowedTimePerPeriodMs() {
|
||||
long[] getAllowedTimePerPeriodMs() {
|
||||
return mAllowedTimePerPeriodMs;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSess
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
|
||||
import static com.android.server.job.JobSchedulerService.ACTIVE_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.EXEMPTED_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.FREQUENT_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.NEVER_INDEX;
|
||||
import static com.android.server.job.JobSchedulerService.RARE_INDEX;
|
||||
@@ -536,6 +537,7 @@ public class QuotaControllerTest {
|
||||
|
||||
ExecutionStats expectedStats = new ExecutionStats();
|
||||
expectedStats.expirationTimeElapsed = now + 24 * HOUR_IN_MILLIS;
|
||||
expectedStats.allowedTimePerPeriodMs = 10 * MINUTE_IN_MILLIS;
|
||||
expectedStats.windowSizeMs = 24 * HOUR_IN_MILLIS;
|
||||
expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_RARE;
|
||||
expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_RARE;
|
||||
@@ -595,6 +597,7 @@ public class QuotaControllerTest {
|
||||
assertNotNull(mQuotaController.getEJTimingSessions(10, "com.android.test"));
|
||||
|
||||
ExecutionStats expectedStats = new ExecutionStats();
|
||||
expectedStats.allowedTimePerPeriodMs = 10 * MINUTE_IN_MILLIS;
|
||||
expectedStats.expirationTimeElapsed = now + 24 * HOUR_IN_MILLIS;
|
||||
expectedStats.windowSizeMs = 24 * HOUR_IN_MILLIS;
|
||||
expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_RARE;
|
||||
@@ -638,11 +641,13 @@ public class QuotaControllerTest {
|
||||
ExecutionStats expectedStats = new ExecutionStats();
|
||||
ExecutionStats inputStats = new ExecutionStats();
|
||||
|
||||
inputStats.allowedTimePerPeriodMs = 10 * MINUTE_IN_MILLIS;
|
||||
inputStats.windowSizeMs = expectedStats.windowSizeMs = 12 * HOUR_IN_MILLIS;
|
||||
inputStats.jobCountLimit = expectedStats.jobCountLimit = 100;
|
||||
inputStats.sessionCountLimit = expectedStats.sessionCountLimit = 100;
|
||||
// Invalid time is now +24 hours since there are no sessions at all for the app.
|
||||
expectedStats.expirationTimeElapsed = now + 24 * HOUR_IN_MILLIS;
|
||||
expectedStats.allowedTimePerPeriodMs = 10 * MINUTE_IN_MILLIS;
|
||||
synchronized (mQuotaController.mLock) {
|
||||
mQuotaController.updateExecutionStatsLocked(0, "com.android.test.not.run", inputStats);
|
||||
}
|
||||
@@ -827,6 +832,8 @@ public class QuotaControllerTest {
|
||||
|
||||
ExecutionStats expectedStats = new ExecutionStats();
|
||||
ExecutionStats inputStats = new ExecutionStats();
|
||||
inputStats.allowedTimePerPeriodMs = expectedStats.allowedTimePerPeriodMs =
|
||||
10 * MINUTE_IN_MILLIS;
|
||||
inputStats.windowSizeMs = expectedStats.windowSizeMs = 24 * HOUR_IN_MILLIS;
|
||||
inputStats.jobCountLimit = expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_RARE;
|
||||
inputStats.sessionCountLimit = expectedStats.sessionCountLimit =
|
||||
@@ -924,6 +931,7 @@ public class QuotaControllerTest {
|
||||
ExecutionStats expectedStats = new ExecutionStats();
|
||||
|
||||
// Active
|
||||
expectedStats.allowedTimePerPeriodMs = 10 * MINUTE_IN_MILLIS;
|
||||
expectedStats.windowSizeMs = 10 * MINUTE_IN_MILLIS;
|
||||
expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_ACTIVE;
|
||||
expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_ACTIVE;
|
||||
@@ -1006,6 +1014,7 @@ public class QuotaControllerTest {
|
||||
ExecutionStats expectedStats = new ExecutionStats();
|
||||
|
||||
// Active
|
||||
expectedStats.allowedTimePerPeriodMs = 10 * MINUTE_IN_MILLIS;
|
||||
expectedStats.windowSizeMs = 10 * MINUTE_IN_MILLIS;
|
||||
expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_ACTIVE;
|
||||
expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_ACTIVE;
|
||||
@@ -1242,6 +1251,7 @@ public class QuotaControllerTest {
|
||||
setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_FREQUENT_MS, 6 * HOUR_IN_MILLIS);
|
||||
|
||||
ExecutionStats expectedStats = new ExecutionStats();
|
||||
expectedStats.allowedTimePerPeriodMs = originalStatsActive.allowedTimePerPeriodMs;
|
||||
expectedStats.windowSizeMs = originalStatsActive.windowSizeMs;
|
||||
expectedStats.jobCountLimit = originalStatsActive.jobCountLimit;
|
||||
expectedStats.sessionCountLimit = originalStatsActive.sessionCountLimit;
|
||||
@@ -1261,6 +1271,7 @@ public class QuotaControllerTest {
|
||||
assertTrue(originalStatsActive == newStatsActive);
|
||||
assertEquals(expectedStats, newStatsActive);
|
||||
|
||||
expectedStats.allowedTimePerPeriodMs = originalStatsWorking.allowedTimePerPeriodMs;
|
||||
expectedStats.windowSizeMs = originalStatsWorking.windowSizeMs;
|
||||
expectedStats.jobCountLimit = originalStatsWorking.jobCountLimit;
|
||||
expectedStats.sessionCountLimit = originalStatsWorking.sessionCountLimit;
|
||||
@@ -1277,6 +1288,7 @@ public class QuotaControllerTest {
|
||||
assertTrue(originalStatsWorking == newStatsWorking);
|
||||
assertNotEquals(expectedStats, newStatsWorking);
|
||||
|
||||
expectedStats.allowedTimePerPeriodMs = originalStatsFrequent.allowedTimePerPeriodMs;
|
||||
expectedStats.windowSizeMs = originalStatsFrequent.windowSizeMs;
|
||||
expectedStats.jobCountLimit = originalStatsFrequent.jobCountLimit;
|
||||
expectedStats.sessionCountLimit = originalStatsFrequent.sessionCountLimit;
|
||||
@@ -1293,6 +1305,7 @@ public class QuotaControllerTest {
|
||||
assertTrue(originalStatsFrequent == newStatsFrequent);
|
||||
assertNotEquals(expectedStats, newStatsFrequent);
|
||||
|
||||
expectedStats.allowedTimePerPeriodMs = originalStatsRare.allowedTimePerPeriodMs;
|
||||
expectedStats.windowSizeMs = originalStatsRare.windowSizeMs;
|
||||
expectedStats.jobCountLimit = originalStatsRare.jobCountLimit;
|
||||
expectedStats.sessionCountLimit = originalStatsRare.sessionCountLimit;
|
||||
@@ -1354,7 +1367,8 @@ public class QuotaControllerTest {
|
||||
@Test
|
||||
public void testGetMaxJobExecutionTimeLocked_Regular_Active() {
|
||||
JobStatus job = createJobStatus("testGetMaxJobExecutionTimeLocked_Regular_Active", 0);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, 10 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS,
|
||||
10 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_ACTIVE_MS, 10 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_MAX_EXECUTION_TIME_MS, 2 * HOUR_IN_MILLIS);
|
||||
setDischarging();
|
||||
@@ -2886,11 +2900,12 @@ public class QuotaControllerTest {
|
||||
public void testMaybeScheduleStartAlarmLocked_JobCount_RateLimitingWindow() {
|
||||
// Set rate limiting period different from allowed time to confirm code sets based on
|
||||
// the former.
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, 10 * MINUTE_IN_MILLIS);
|
||||
final int standbyBucket = WORKING_INDEX;
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS,
|
||||
10 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_RATE_LIMITING_WINDOW_MS, 5 * MINUTE_IN_MILLIS);
|
||||
|
||||
final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
|
||||
final int standbyBucket = WORKING_INDEX;
|
||||
|
||||
JobStatus jobStatus = createJobStatus("testMaybeScheduleStartAlarmLocked", 1);
|
||||
setStandbyBucket(standbyBucket, jobStatus);
|
||||
@@ -2953,8 +2968,8 @@ public class QuotaControllerTest {
|
||||
@Test
|
||||
public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedAllowedTime() {
|
||||
// Make sure any new value is used correctly.
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS,
|
||||
mQcConstants.ALLOWED_TIME_PER_PERIOD_MS / 2);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS,
|
||||
mQcConstants.ALLOWED_TIME_PER_PERIOD_WORKING_MS / 2);
|
||||
|
||||
runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck();
|
||||
mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
|
||||
@@ -2977,8 +2992,8 @@ public class QuotaControllerTest {
|
||||
// Make sure any new value is used correctly.
|
||||
setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS,
|
||||
mQcConstants.IN_QUOTA_BUFFER_MS * 2);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS,
|
||||
mQcConstants.ALLOWED_TIME_PER_PERIOD_MS / 2);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS,
|
||||
mQcConstants.ALLOWED_TIME_PER_PERIOD_WORKING_MS / 2);
|
||||
setDeviceConfigLong(QcConstants.KEY_MAX_EXECUTION_TIME_MS,
|
||||
mQcConstants.MAX_EXECUTION_TIME_MS / 2);
|
||||
|
||||
@@ -3002,7 +3017,8 @@ public class QuotaControllerTest {
|
||||
// Working set window size is 2 hours.
|
||||
final int standbyBucket = WORKING_INDEX;
|
||||
final long contributionMs = mQcConstants.IN_QUOTA_BUFFER_MS / 2;
|
||||
final long remainingTimeMs = mQcConstants.ALLOWED_TIME_PER_PERIOD_MS - contributionMs;
|
||||
final long remainingTimeMs =
|
||||
mQcConstants.ALLOWED_TIME_PER_PERIOD_WORKING_MS - contributionMs;
|
||||
|
||||
// Session straddles edge of bucket window. Only the contribution should be counted towards
|
||||
// the quota.
|
||||
@@ -3062,16 +3078,28 @@ public class QuotaControllerTest {
|
||||
|
||||
@Test
|
||||
public void testConstantsUpdating_ValidValues() {
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, 5 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS,
|
||||
8 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS,
|
||||
5 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS,
|
||||
7 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS,
|
||||
2 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_RARE_MS, 4 * MINUTE_IN_MILLIS);
|
||||
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);
|
||||
setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_FREQUENT_MS, 45 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_RARE_MS, 60 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_RESTRICTED_MS, 120 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_MAX_EXECUTION_TIME_MS, 3 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_EXEMPTED, 6000);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_ACTIVE, 5000);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_WORKING, 4000);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_FREQUENT, 3000);
|
||||
@@ -3079,6 +3107,7 @@ public class QuotaControllerTest {
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_RESTRICTED, 2000);
|
||||
setDeviceConfigLong(QcConstants.KEY_RATE_LIMITING_WINDOW_MS, 15 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW, 500);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_EXEMPTED, 600);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_ACTIVE, 500);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_WORKING, 400);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_FREQUENT, 300);
|
||||
@@ -3088,6 +3117,7 @@ public class QuotaControllerTest {
|
||||
setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS,
|
||||
10 * SECOND_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_MIN_QUOTA_CHECK_DELAY_MS, 7 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_EXEMPTED_MS, 3 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_ACTIVE_MS, 2 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_WORKING_MS, 90 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_FREQUENT_MS, 1 * HOUR_IN_MILLIS);
|
||||
@@ -3104,10 +3134,23 @@ public class QuotaControllerTest {
|
||||
84 * SECOND_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_GRACE_PERIOD_TOP_APP_MS, 83 * SECOND_IN_MILLIS);
|
||||
|
||||
assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
|
||||
assertEquals(8 * MINUTE_IN_MILLIS,
|
||||
mQuotaController.getAllowedTimePerPeriodMs()[EXEMPTED_INDEX]);
|
||||
assertEquals(5 * MINUTE_IN_MILLIS,
|
||||
mQuotaController.getAllowedTimePerPeriodMs()[ACTIVE_INDEX]);
|
||||
assertEquals(7 * MINUTE_IN_MILLIS,
|
||||
mQuotaController.getAllowedTimePerPeriodMs()[WORKING_INDEX]);
|
||||
assertEquals(2 * MINUTE_IN_MILLIS,
|
||||
mQuotaController.getAllowedTimePerPeriodMs()[FREQUENT_INDEX]);
|
||||
assertEquals(4 * MINUTE_IN_MILLIS,
|
||||
mQuotaController.getAllowedTimePerPeriodMs()[RARE_INDEX]);
|
||||
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]);
|
||||
assertEquals(30 * MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[WORKING_INDEX]);
|
||||
assertEquals(45 * MINUTE_IN_MILLIS,
|
||||
@@ -3118,12 +3161,14 @@ public class QuotaControllerTest {
|
||||
assertEquals(3 * HOUR_IN_MILLIS, mQuotaController.getMaxExecutionTimeMs());
|
||||
assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getRateLimitingWindowMs());
|
||||
assertEquals(500, mQuotaController.getMaxJobCountPerRateLimitingWindow());
|
||||
assertEquals(6000, mQuotaController.getBucketMaxJobCounts()[EXEMPTED_INDEX]);
|
||||
assertEquals(5000, mQuotaController.getBucketMaxJobCounts()[ACTIVE_INDEX]);
|
||||
assertEquals(4000, mQuotaController.getBucketMaxJobCounts()[WORKING_INDEX]);
|
||||
assertEquals(3000, mQuotaController.getBucketMaxJobCounts()[FREQUENT_INDEX]);
|
||||
assertEquals(2000, mQuotaController.getBucketMaxJobCounts()[RARE_INDEX]);
|
||||
assertEquals(2000, mQuotaController.getBucketMaxJobCounts()[RESTRICTED_INDEX]);
|
||||
assertEquals(50, mQuotaController.getMaxSessionCountPerRateLimitingWindow());
|
||||
assertEquals(600, mQuotaController.getBucketMaxSessionCounts()[EXEMPTED_INDEX]);
|
||||
assertEquals(500, mQuotaController.getBucketMaxSessionCounts()[ACTIVE_INDEX]);
|
||||
assertEquals(400, mQuotaController.getBucketMaxSessionCounts()[WORKING_INDEX]);
|
||||
assertEquals(300, mQuotaController.getBucketMaxSessionCounts()[FREQUENT_INDEX]);
|
||||
@@ -3132,6 +3177,7 @@ public class QuotaControllerTest {
|
||||
assertEquals(10 * SECOND_IN_MILLIS,
|
||||
mQuotaController.getTimingSessionCoalescingDurationMs());
|
||||
assertEquals(7 * MINUTE_IN_MILLIS, mQuotaController.getMinQuotaCheckDelayMs());
|
||||
assertEquals(3 * HOUR_IN_MILLIS, mQuotaController.getEJLimitsMs()[EXEMPTED_INDEX]);
|
||||
assertEquals(2 * HOUR_IN_MILLIS, mQuotaController.getEJLimitsMs()[ACTIVE_INDEX]);
|
||||
assertEquals(90 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[WORKING_INDEX]);
|
||||
assertEquals(HOUR_IN_MILLIS, mQuotaController.getEJLimitsMs()[FREQUENT_INDEX]);
|
||||
@@ -3151,16 +3197,24 @@ public class QuotaControllerTest {
|
||||
@Test
|
||||
public void testConstantsUpdating_InvalidValues() {
|
||||
// Test negatives/too low.
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, -MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS, -MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS, -MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS, -MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS, -MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_RARE_MS, -MINUTE_IN_MILLIS);
|
||||
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);
|
||||
setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_FREQUENT_MS, -MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_RARE_MS, -MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_RESTRICTED_MS, -MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_MAX_EXECUTION_TIME_MS, -MINUTE_IN_MILLIS);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_EXEMPTED, -1);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_ACTIVE, -1);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_WORKING, 1);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_FREQUENT, 1);
|
||||
@@ -3168,6 +3222,7 @@ public class QuotaControllerTest {
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_RESTRICTED, -1);
|
||||
setDeviceConfigLong(QcConstants.KEY_RATE_LIMITING_WINDOW_MS, 15 * SECOND_IN_MILLIS);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW, 0);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_EXEMPTED, -1);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_ACTIVE, -1);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_WORKING, 0);
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_FREQUENT, -3);
|
||||
@@ -3176,6 +3231,7 @@ public class QuotaControllerTest {
|
||||
setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_PER_RATE_LIMITING_WINDOW, 0);
|
||||
setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, -1);
|
||||
setDeviceConfigLong(QcConstants.KEY_MIN_QUOTA_CHECK_DELAY_MS, -1);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_EXEMPTED_MS, -1);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_ACTIVE_MS, -1);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_WORKING_MS, -1);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_FREQUENT_MS, -1);
|
||||
@@ -3191,10 +3247,19 @@ public class QuotaControllerTest {
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_GRACE_PERIOD_TEMP_ALLOWLIST_MS, -1);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_GRACE_PERIOD_TOP_APP_MS, -1);
|
||||
|
||||
assertEquals(MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
|
||||
assertEquals(MINUTE_IN_MILLIS,
|
||||
mQuotaController.getAllowedTimePerPeriodMs()[EXEMPTED_INDEX]);
|
||||
assertEquals(MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs()[ACTIVE_INDEX]);
|
||||
assertEquals(MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs()[WORKING_INDEX]);
|
||||
assertEquals(MINUTE_IN_MILLIS,
|
||||
mQuotaController.getAllowedTimePerPeriodMs()[FREQUENT_INDEX]);
|
||||
assertEquals(MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs()[RARE_INDEX]);
|
||||
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]);
|
||||
assertEquals(MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[FREQUENT_INDEX]);
|
||||
@@ -3203,12 +3268,14 @@ public class QuotaControllerTest {
|
||||
assertEquals(HOUR_IN_MILLIS, mQuotaController.getMaxExecutionTimeMs());
|
||||
assertEquals(30 * SECOND_IN_MILLIS, mQuotaController.getRateLimitingWindowMs());
|
||||
assertEquals(10, mQuotaController.getMaxJobCountPerRateLimitingWindow());
|
||||
assertEquals(10, mQuotaController.getBucketMaxJobCounts()[EXEMPTED_INDEX]);
|
||||
assertEquals(10, mQuotaController.getBucketMaxJobCounts()[ACTIVE_INDEX]);
|
||||
assertEquals(10, mQuotaController.getBucketMaxJobCounts()[WORKING_INDEX]);
|
||||
assertEquals(10, mQuotaController.getBucketMaxJobCounts()[FREQUENT_INDEX]);
|
||||
assertEquals(10, mQuotaController.getBucketMaxJobCounts()[RARE_INDEX]);
|
||||
assertEquals(10, mQuotaController.getBucketMaxJobCounts()[RESTRICTED_INDEX]);
|
||||
assertEquals(10, mQuotaController.getMaxSessionCountPerRateLimitingWindow());
|
||||
assertEquals(1, mQuotaController.getBucketMaxSessionCounts()[EXEMPTED_INDEX]);
|
||||
assertEquals(1, mQuotaController.getBucketMaxSessionCounts()[ACTIVE_INDEX]);
|
||||
assertEquals(1, mQuotaController.getBucketMaxSessionCounts()[WORKING_INDEX]);
|
||||
assertEquals(1, mQuotaController.getBucketMaxSessionCounts()[FREQUENT_INDEX]);
|
||||
@@ -3216,6 +3283,7 @@ public class QuotaControllerTest {
|
||||
assertEquals(0, mQuotaController.getBucketMaxSessionCounts()[RESTRICTED_INDEX]);
|
||||
assertEquals(0, mQuotaController.getTimingSessionCoalescingDurationMs());
|
||||
assertEquals(0, mQuotaController.getMinQuotaCheckDelayMs());
|
||||
assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[EXEMPTED_INDEX]);
|
||||
assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[ACTIVE_INDEX]);
|
||||
assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[WORKING_INDEX]);
|
||||
assertEquals(10 * MINUTE_IN_MILLIS, mQuotaController.getEJLimitsMs()[FREQUENT_INDEX]);
|
||||
@@ -3233,17 +3301,37 @@ public class QuotaControllerTest {
|
||||
|
||||
// Invalid configurations.
|
||||
// In_QUOTA_BUFFER should never be greater than ALLOWED_TIME_PER_PERIOD
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, 2 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS,
|
||||
10 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS,
|
||||
10 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS,
|
||||
10 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS,
|
||||
2 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_RARE_MS, 10 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS,
|
||||
10 * MINUTE_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, 5 * MINUTE_IN_MILLIS);
|
||||
|
||||
assertTrue(mQuotaController.getInQuotaBufferMs()
|
||||
<= mQuotaController.getAllowedTimePerPeriodMs());
|
||||
<= mQuotaController.getAllowedTimePerPeriodMs()[FREQUENT_INDEX]);
|
||||
|
||||
// Test larger than a day. Controller should cap at one day.
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_MS, 25 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS,
|
||||
25 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS, 25 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS,
|
||||
25 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS,
|
||||
25 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_RARE_MS, 25 * HOUR_IN_MILLIS);
|
||||
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);
|
||||
setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_FREQUENT_MS, 25 * HOUR_IN_MILLIS);
|
||||
@@ -3254,6 +3342,7 @@ public class QuotaControllerTest {
|
||||
setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS,
|
||||
25 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_MIN_QUOTA_CHECK_DELAY_MS, 25 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_EXEMPTED_MS, 25 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_ACTIVE_MS, 25 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_WORKING_MS, 25 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_LIMIT_FREQUENT_MS, 25 * HOUR_IN_MILLIS);
|
||||
@@ -3269,10 +3358,21 @@ public class QuotaControllerTest {
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_GRACE_PERIOD_TEMP_ALLOWLIST_MS, 25 * HOUR_IN_MILLIS);
|
||||
setDeviceConfigLong(QcConstants.KEY_EJ_GRACE_PERIOD_TOP_APP_MS, 25 * HOUR_IN_MILLIS);
|
||||
|
||||
assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
|
||||
assertEquals(24 * HOUR_IN_MILLIS,
|
||||
mQuotaController.getAllowedTimePerPeriodMs()[EXEMPTED_INDEX]);
|
||||
assertEquals(24 * HOUR_IN_MILLIS,
|
||||
mQuotaController.getAllowedTimePerPeriodMs()[ACTIVE_INDEX]);
|
||||
assertEquals(24 * HOUR_IN_MILLIS,
|
||||
mQuotaController.getAllowedTimePerPeriodMs()[WORKING_INDEX]);
|
||||
assertEquals(24 * HOUR_IN_MILLIS,
|
||||
mQuotaController.getAllowedTimePerPeriodMs()[FREQUENT_INDEX]);
|
||||
assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs()[RARE_INDEX]);
|
||||
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]);
|
||||
assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getBucketWindowSizes()[FREQUENT_INDEX]);
|
||||
@@ -3284,6 +3384,7 @@ public class QuotaControllerTest {
|
||||
assertEquals(15 * MINUTE_IN_MILLIS,
|
||||
mQuotaController.getTimingSessionCoalescingDurationMs());
|
||||
assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getMinQuotaCheckDelayMs());
|
||||
assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getEJLimitsMs()[EXEMPTED_INDEX]);
|
||||
assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getEJLimitsMs()[ACTIVE_INDEX]);
|
||||
assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getEJLimitsMs()[WORKING_INDEX]);
|
||||
assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getEJLimitsMs()[FREQUENT_INDEX]);
|
||||
|
||||
Reference in New Issue
Block a user