Loading apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +17 −11 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.AlarmManager; import android.app.UidObserver; import android.app.job.JobInfo; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal.UsageEventListener; Loading Loading @@ -772,7 +773,9 @@ public final class QuotaController extends StateController { if (!jobStatus.shouldTreatAsExpeditedJob()) { // If quota is currently "free", then the job can run for the full amount of time, // regardless of bucket (hence using charging instead of isQuotaFreeLocked()). if (mService.isBatteryCharging() if (mService.isBatteryCharging()) { return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS; } // The top and foreground cases here were added because apps in those states // aren't really restricted and the work could be something the user is // waiting for. Now that user-initiated jobs are a defined concept, we may Loading @@ -781,9 +784,12 @@ public final class QuotaController extends StateController { // rely on this exception. Once we add more UIJ types, we can re-evaluate // the need for these exceptions. // TODO: re-evaluate the need for these exceptions || mTopAppCache.get(jobStatus.getSourceUid()) final boolean isInPrivilegedState = mTopAppCache.get(jobStatus.getSourceUid()) || isTopStartedJobLocked(jobStatus) || isUidInForeground(jobStatus.getSourceUid())) { || isUidInForeground(jobStatus.getSourceUid()); final boolean isJobImportant = jobStatus.getEffectivePriority() >= JobInfo.PRIORITY_HIGH || (jobStatus.getFlags() & JobInfo.FLAG_IMPORTANT_WHILE_FOREGROUND) != 0; if (isInPrivilegedState && isJobImportant) { return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS; } return getTimeUntilQuotaConsumedLocked( Loading services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java +43 −7 Original line number Diff line number Diff line Loading @@ -368,10 +368,15 @@ public class QuotaControllerTest { } } private JobInfo.Builder createJobInfoBuilder(int jobId) { return new JobInfo.Builder(jobId, new ComponentName(mContext, "TestQuotaJobService")); } private JobStatus createJobStatus(String testTag, int jobId) { JobInfo jobInfo = new JobInfo.Builder(jobId, new ComponentName(mContext, "TestQuotaJobService")) .build(); return createJobStatus(testTag, createJobInfoBuilder(jobId).build()); } private JobStatus createJobStatus(String testTag, JobInfo jobInfo) { return createJobStatus(testTag, SOURCE_PACKAGE, CALLING_UID, jobInfo); } Loading Loading @@ -1333,39 +1338,70 @@ public class QuotaControllerTest { mQuotaController.saveTimingSession(0, SOURCE_PACKAGE, createTimingSession(sElapsedRealtimeClock.millis() - (6 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false); final long timeUntilQuotaConsumedMs = 7 * MINUTE_IN_MILLIS; JobStatus job = createJobStatus("testGetMaxJobExecutionTimeLocked", 0); //noinspection deprecation JobStatus jobDefIWF = createJobStatus("testGetMaxJobExecutionTimeLocked", createJobInfoBuilder(1) .setImportantWhileForeground(true) .setPriority(JobInfo.PRIORITY_DEFAULT) .build()); JobStatus jobHigh = createJobStatus("testGetMaxJobExecutionTimeLocked", createJobInfoBuilder(2).setPriority(JobInfo.PRIORITY_HIGH).build()); setStandbyBucket(RARE_INDEX, job); setStandbyBucket(RARE_INDEX, jobDefIWF); setStandbyBucket(RARE_INDEX, jobHigh); setCharging(); synchronized (mQuotaController.mLock) { assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobDefIWF))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobHigh))); } setDischarging(); setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); synchronized (mQuotaController.mLock) { assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, assertEquals(timeUntilQuotaConsumedMs, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobDefIWF))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobHigh))); } // Top-started job setProcessState(ActivityManager.PROCESS_STATE_TOP); synchronized (mQuotaController.mLock) { mQuotaController.maybeStartTrackingJobLocked(job, null); trackJobs(job, jobDefIWF, jobHigh); mQuotaController.prepareForExecutionLocked(job); mQuotaController.prepareForExecutionLocked(jobDefIWF); mQuotaController.prepareForExecutionLocked(jobHigh); } setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); synchronized (mQuotaController.mLock) { assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, assertEquals(timeUntilQuotaConsumedMs, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobDefIWF))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobHigh))); mQuotaController.maybeStopTrackingJobLocked(job, null); mQuotaController.maybeStopTrackingJobLocked(jobDefIWF, null); mQuotaController.maybeStopTrackingJobLocked(jobHigh, null); } setProcessState(ActivityManager.PROCESS_STATE_RECEIVER); synchronized (mQuotaController.mLock) { assertEquals(7 * MINUTE_IN_MILLIS, assertEquals(timeUntilQuotaConsumedMs, mQuotaController.getMaxJobExecutionTimeMsLocked(job)); assertEquals(timeUntilQuotaConsumedMs, mQuotaController.getMaxJobExecutionTimeMsLocked(jobDefIWF)); assertEquals(timeUntilQuotaConsumedMs, mQuotaController.getMaxJobExecutionTimeMsLocked(jobHigh)); } } Loading Loading
apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +17 −11 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.AlarmManager; import android.app.UidObserver; import android.app.job.JobInfo; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal.UsageEventListener; Loading Loading @@ -772,7 +773,9 @@ public final class QuotaController extends StateController { if (!jobStatus.shouldTreatAsExpeditedJob()) { // If quota is currently "free", then the job can run for the full amount of time, // regardless of bucket (hence using charging instead of isQuotaFreeLocked()). if (mService.isBatteryCharging() if (mService.isBatteryCharging()) { return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS; } // The top and foreground cases here were added because apps in those states // aren't really restricted and the work could be something the user is // waiting for. Now that user-initiated jobs are a defined concept, we may Loading @@ -781,9 +784,12 @@ public final class QuotaController extends StateController { // rely on this exception. Once we add more UIJ types, we can re-evaluate // the need for these exceptions. // TODO: re-evaluate the need for these exceptions || mTopAppCache.get(jobStatus.getSourceUid()) final boolean isInPrivilegedState = mTopAppCache.get(jobStatus.getSourceUid()) || isTopStartedJobLocked(jobStatus) || isUidInForeground(jobStatus.getSourceUid())) { || isUidInForeground(jobStatus.getSourceUid()); final boolean isJobImportant = jobStatus.getEffectivePriority() >= JobInfo.PRIORITY_HIGH || (jobStatus.getFlags() & JobInfo.FLAG_IMPORTANT_WHILE_FOREGROUND) != 0; if (isInPrivilegedState && isJobImportant) { return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS; } return getTimeUntilQuotaConsumedLocked( Loading
services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java +43 −7 Original line number Diff line number Diff line Loading @@ -368,10 +368,15 @@ public class QuotaControllerTest { } } private JobInfo.Builder createJobInfoBuilder(int jobId) { return new JobInfo.Builder(jobId, new ComponentName(mContext, "TestQuotaJobService")); } private JobStatus createJobStatus(String testTag, int jobId) { JobInfo jobInfo = new JobInfo.Builder(jobId, new ComponentName(mContext, "TestQuotaJobService")) .build(); return createJobStatus(testTag, createJobInfoBuilder(jobId).build()); } private JobStatus createJobStatus(String testTag, JobInfo jobInfo) { return createJobStatus(testTag, SOURCE_PACKAGE, CALLING_UID, jobInfo); } Loading Loading @@ -1333,39 +1338,70 @@ public class QuotaControllerTest { mQuotaController.saveTimingSession(0, SOURCE_PACKAGE, createTimingSession(sElapsedRealtimeClock.millis() - (6 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false); final long timeUntilQuotaConsumedMs = 7 * MINUTE_IN_MILLIS; JobStatus job = createJobStatus("testGetMaxJobExecutionTimeLocked", 0); //noinspection deprecation JobStatus jobDefIWF = createJobStatus("testGetMaxJobExecutionTimeLocked", createJobInfoBuilder(1) .setImportantWhileForeground(true) .setPriority(JobInfo.PRIORITY_DEFAULT) .build()); JobStatus jobHigh = createJobStatus("testGetMaxJobExecutionTimeLocked", createJobInfoBuilder(2).setPriority(JobInfo.PRIORITY_HIGH).build()); setStandbyBucket(RARE_INDEX, job); setStandbyBucket(RARE_INDEX, jobDefIWF); setStandbyBucket(RARE_INDEX, jobHigh); setCharging(); synchronized (mQuotaController.mLock) { assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobDefIWF))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobHigh))); } setDischarging(); setProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); synchronized (mQuotaController.mLock) { assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, assertEquals(timeUntilQuotaConsumedMs, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobDefIWF))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobHigh))); } // Top-started job setProcessState(ActivityManager.PROCESS_STATE_TOP); synchronized (mQuotaController.mLock) { mQuotaController.maybeStartTrackingJobLocked(job, null); trackJobs(job, jobDefIWF, jobHigh); mQuotaController.prepareForExecutionLocked(job); mQuotaController.prepareForExecutionLocked(jobDefIWF); mQuotaController.prepareForExecutionLocked(jobHigh); } setProcessState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); synchronized (mQuotaController.mLock) { assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, assertEquals(timeUntilQuotaConsumedMs, mQuotaController.getMaxJobExecutionTimeMsLocked((job))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobDefIWF))); assertEquals(JobSchedulerService.Constants.DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, mQuotaController.getMaxJobExecutionTimeMsLocked((jobHigh))); mQuotaController.maybeStopTrackingJobLocked(job, null); mQuotaController.maybeStopTrackingJobLocked(jobDefIWF, null); mQuotaController.maybeStopTrackingJobLocked(jobHigh, null); } setProcessState(ActivityManager.PROCESS_STATE_RECEIVER); synchronized (mQuotaController.mLock) { assertEquals(7 * MINUTE_IN_MILLIS, assertEquals(timeUntilQuotaConsumedMs, mQuotaController.getMaxJobExecutionTimeMsLocked(job)); assertEquals(timeUntilQuotaConsumedMs, mQuotaController.getMaxJobExecutionTimeMsLocked(jobDefIWF)); assertEquals(timeUntilQuotaConsumedMs, mQuotaController.getMaxJobExecutionTimeMsLocked(jobHigh)); } } Loading