Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be070f30 authored by Kweku Adams's avatar Kweku Adams Committed by Android (Google) Code Review
Browse files

Merge "Limit execution extension to important jobs." into main

parents fade449f a8e4b0aa
Loading
Loading
Loading
Loading
+17 −11
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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(
+43 −7
Original line number Diff line number Diff line
@@ -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);
    }

@@ -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));
        }
    }