Loading apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +2 −1 Original line number Diff line number Diff line Loading @@ -2293,7 +2293,8 @@ public class JobSchedulerService extends com.android.server.SystemService /** Returns the maximum amount of time this job could run for. */ public long getMaxJobExecutionTimeMs(JobStatus job) { synchronized (mLock) { return mQuotaController.getMaxJobExecutionTimeMsLocked(job); return Math.min(mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked(job)); } } Loading apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +7 −1 Original line number Diff line number Diff line Loading @@ -995,12 +995,18 @@ public final class QuotaController extends StateController { if (standbyBucket == NEVER_INDEX) { return 0; } List<TimingSession> sessions = mTimingSessions.get(userId, packageName); final ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket); 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) { return mMaxExecutionTimeMs; } return mAllowedTimePerPeriodMs; } final ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket); final long startWindowElapsed = nowElapsed - stats.windowSizeMs; final long startMaxElapsed = nowElapsed - MAX_PERIOD_MS; final long allowedTimeRemainingMs = mAllowedTimePerPeriodMs - stats.executionTimeInWindowMs; Loading services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java +40 −0 Original line number Diff line number Diff line Loading @@ -1325,6 +1325,46 @@ 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_WINDOW_SIZE_ACTIVE_MS, 10 * MINUTE_IN_MILLIS); setDeviceConfigLong(QcConstants.KEY_MAX_EXECUTION_TIME_MS, 2 * HOUR_IN_MILLIS); setDischarging(); setStandbyBucket(ACTIVE_INDEX, job); setProcessState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); // ACTIVE apps (where allowed time = window size) should be capped at max execution limit. synchronized (mQuotaController.mLock) { assertEquals(2 * HOUR_IN_MILLIS, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); } // Make sure sessions are factored in properly. mQuotaController.saveTimingSession(0, SOURCE_PACKAGE, createTimingSession(sElapsedRealtimeClock.millis() - (6 * HOUR_IN_MILLIS), 30 * MINUTE_IN_MILLIS, 1), false); synchronized (mQuotaController.mLock) { assertEquals(90 * MINUTE_IN_MILLIS, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); } mQuotaController.saveTimingSession(0, SOURCE_PACKAGE, createTimingSession(sElapsedRealtimeClock.millis() - (5 * HOUR_IN_MILLIS), 30 * MINUTE_IN_MILLIS, 1), false); mQuotaController.saveTimingSession(0, SOURCE_PACKAGE, createTimingSession(sElapsedRealtimeClock.millis() - (4 * HOUR_IN_MILLIS), 30 * MINUTE_IN_MILLIS, 1), false); mQuotaController.saveTimingSession(0, SOURCE_PACKAGE, createTimingSession(sElapsedRealtimeClock.millis() - (3 * HOUR_IN_MILLIS), 25 * MINUTE_IN_MILLIS, 1), false); synchronized (mQuotaController.mLock) { assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); } } @Test public void testGetMaxJobExecutionTimeLocked_EJ() { final long timeUsedMs = 3 * MINUTE_IN_MILLIS; Loading Loading
apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +2 −1 Original line number Diff line number Diff line Loading @@ -2293,7 +2293,8 @@ public class JobSchedulerService extends com.android.server.SystemService /** Returns the maximum amount of time this job could run for. */ public long getMaxJobExecutionTimeMs(JobStatus job) { synchronized (mLock) { return mQuotaController.getMaxJobExecutionTimeMsLocked(job); return Math.min(mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked(job)); } } Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +7 −1 Original line number Diff line number Diff line Loading @@ -995,12 +995,18 @@ public final class QuotaController extends StateController { if (standbyBucket == NEVER_INDEX) { return 0; } List<TimingSession> sessions = mTimingSessions.get(userId, packageName); final ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket); 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) { return mMaxExecutionTimeMs; } return mAllowedTimePerPeriodMs; } final ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket); final long startWindowElapsed = nowElapsed - stats.windowSizeMs; final long startMaxElapsed = nowElapsed - MAX_PERIOD_MS; final long allowedTimeRemainingMs = mAllowedTimePerPeriodMs - stats.executionTimeInWindowMs; Loading
services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java +40 −0 Original line number Diff line number Diff line Loading @@ -1325,6 +1325,46 @@ 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_WINDOW_SIZE_ACTIVE_MS, 10 * MINUTE_IN_MILLIS); setDeviceConfigLong(QcConstants.KEY_MAX_EXECUTION_TIME_MS, 2 * HOUR_IN_MILLIS); setDischarging(); setStandbyBucket(ACTIVE_INDEX, job); setProcessState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY); // ACTIVE apps (where allowed time = window size) should be capped at max execution limit. synchronized (mQuotaController.mLock) { assertEquals(2 * HOUR_IN_MILLIS, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); } // Make sure sessions are factored in properly. mQuotaController.saveTimingSession(0, SOURCE_PACKAGE, createTimingSession(sElapsedRealtimeClock.millis() - (6 * HOUR_IN_MILLIS), 30 * MINUTE_IN_MILLIS, 1), false); synchronized (mQuotaController.mLock) { assertEquals(90 * MINUTE_IN_MILLIS, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); } mQuotaController.saveTimingSession(0, SOURCE_PACKAGE, createTimingSession(sElapsedRealtimeClock.millis() - (5 * HOUR_IN_MILLIS), 30 * MINUTE_IN_MILLIS, 1), false); mQuotaController.saveTimingSession(0, SOURCE_PACKAGE, createTimingSession(sElapsedRealtimeClock.millis() - (4 * HOUR_IN_MILLIS), 30 * MINUTE_IN_MILLIS, 1), false); mQuotaController.saveTimingSession(0, SOURCE_PACKAGE, createTimingSession(sElapsedRealtimeClock.millis() - (3 * HOUR_IN_MILLIS), 25 * MINUTE_IN_MILLIS, 1), false); synchronized (mQuotaController.mLock) { assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); } } @Test public void testGetMaxJobExecutionTimeLocked_EJ() { final long timeUsedMs = 3 * MINUTE_IN_MILLIS; Loading