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

Commit 8a94f6b5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Make sure RESTRICTED quota is properly counted." into sc-dev am: a071ad39

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14432990

Change-Id: I64f4e41dd136b823844ee67a0a51fa51377f7a6f
parents 2ed5ad14 a071ad39
Loading
Loading
Loading
Loading
+33 −16
Original line number Diff line number Diff line
@@ -621,6 +621,7 @@ public final class QuotaController extends StateController {
    }

    @Override
    @GuardedBy("mLock")
    public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
        final long nowElapsed = sElapsedRealtimeClock.millis();
        final int userId = jobStatus.getSourceUserId();
@@ -648,6 +649,7 @@ public final class QuotaController extends StateController {
    }

    @Override
    @GuardedBy("mLock")
    public void prepareForExecutionLocked(JobStatus jobStatus) {
        if (DEBUG) {
            Slog.d(TAG, "Prepping for " + jobStatus.toShortString());
@@ -676,6 +678,7 @@ public final class QuotaController extends StateController {
    }

    @Override
    @GuardedBy("mLock")
    public void unprepareFromExecutionLocked(JobStatus jobStatus) {
        Timer timer = mPkgTimers.get(jobStatus.getSourceUserId(), jobStatus.getSourcePackageName());
        if (timer != null) {
@@ -691,6 +694,7 @@ public final class QuotaController extends StateController {
    }

    @Override
    @GuardedBy("mLock")
    public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
            boolean forUpdate) {
        if (jobStatus.clearTrackingController(JobStatus.TRACKING_QUOTA)) {
@@ -796,10 +800,12 @@ public final class QuotaController extends StateController {
    }

    /** Returns the maximum amount of time this job could run for. */
    @GuardedBy("mLock")
    public long getMaxJobExecutionTimeMsLocked(@NonNull final JobStatus jobStatus) {
        if (!jobStatus.shouldTreatAsExpeditedJob()) {
            // If quota is currently "free", then the job can run for the full amount of time.
            if (mChargeTracker.isCharging()
            // 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 (mChargeTracker.isChargingLocked()
                    || mTopAppCache.get(jobStatus.getSourceUid())
                    || isTopStartedJobLocked(jobStatus)
                    || isUidInForeground(jobStatus.getSourceUid())) {
@@ -810,7 +816,7 @@ public final class QuotaController extends StateController {
        }

        // Expedited job.
        if (mChargeTracker.isCharging()) {
        if (mChargeTracker.isChargingLocked()) {
            return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS;
        }
        if (mTopAppCache.get(jobStatus.getSourceUid()) || isTopStartedJobLocked(jobStatus)) {
@@ -828,8 +834,9 @@ public final class QuotaController extends StateController {
    }

    /** @return true if the job is within expedited job quota. */
    @GuardedBy("mLock")
    public boolean isWithinEJQuotaLocked(@NonNull final JobStatus jobStatus) {
        if (isQuotaFree(jobStatus.getEffectiveStandbyBucket())) {
        if (isQuotaFreeLocked(jobStatus.getEffectiveStandbyBucket())) {
            return true;
        }
        // A job is within quota if one of the following is true:
@@ -887,9 +894,10 @@ public final class QuotaController extends StateController {
                jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(), standbyBucket);
    }

    private boolean isQuotaFree(final int standbyBucket) {
    @GuardedBy("mLock")
    private boolean isQuotaFreeLocked(final int standbyBucket) {
        // Quota constraint is not enforced while charging.
        if (mChargeTracker.isCharging()) {
        if (mChargeTracker.isChargingLocked()) {
            // Restricted jobs require additional constraints when charging, so don't immediately
            // mark quota as free when charging.
            return standbyBucket != RESTRICTED_INDEX;
@@ -898,11 +906,12 @@ public final class QuotaController extends StateController {
    }

    @VisibleForTesting
    @GuardedBy("mLock")
    boolean isWithinQuotaLocked(final int userId, @NonNull final String packageName,
            final int standbyBucket) {
        if (standbyBucket == NEVER_INDEX) return false;

        if (isQuotaFree(standbyBucket)) return true;
        if (isQuotaFreeLocked(standbyBucket)) return true;

        ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket);
        return getRemainingExecutionTimeLocked(stats) > 0
@@ -1556,9 +1565,9 @@ public final class QuotaController extends StateController {

    private void handleNewChargingStateLocked() {
        mTimerChargingUpdateFunctor.setStatus(sElapsedRealtimeClock.millis(),
                mChargeTracker.isCharging());
                mChargeTracker.isChargingLocked());
        if (DEBUG) {
            Slog.d(TAG, "handleNewChargingStateLocked: " + mChargeTracker.isCharging());
            Slog.d(TAG, "handleNewChargingStateLocked: " + mChargeTracker.isChargingLocked());
        }
        // Deal with Timers first.
        mEJPkgTimers.forEach(mTimerChargingUpdateFunctor);
@@ -1827,6 +1836,7 @@ public final class QuotaController extends StateController {
         * Track whether we're charging. This has a slightly different definition than that of
         * BatteryController.
         */
        @GuardedBy("mLock")
        private boolean mCharging;

        ChargingTracker() {
@@ -1846,7 +1856,8 @@ public final class QuotaController extends StateController {
            mCharging = batteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
        }

        public boolean isCharging() {
        @GuardedBy("mLock")
        public boolean isChargingLocked() {
            return mCharging;
        }

@@ -2055,9 +2066,12 @@ public final class QuotaController extends StateController {
                    }
                    return;
                }
                if (mRunningBgJobs.remove(jobStatus)
                        && !mChargeTracker.isCharging() && mRunningBgJobs.size() == 0) {
                    emitSessionLocked(sElapsedRealtimeClock.millis());
                final long nowElapsed = sElapsedRealtimeClock.millis();
                final int standbyBucket = JobSchedulerService.standbyBucketForPackage(
                        mPkg.packageName, mPkg.userId, nowElapsed);
                if (mRunningBgJobs.remove(jobStatus) && mRunningBgJobs.size() == 0
                        && !isQuotaFreeLocked(standbyBucket)) {
                    emitSessionLocked(nowElapsed);
                    cancelCutoff();
                }
            }
@@ -2077,6 +2091,7 @@ public final class QuotaController extends StateController {
            cancelCutoff();
        }

        @GuardedBy("mLock")
        private void emitSessionLocked(long nowElapsed) {
            if (mBgJobCount <= 0) {
                // Nothing to emit.
@@ -2121,6 +2136,7 @@ public final class QuotaController extends StateController {
            }
        }

        @GuardedBy("mLock")
        private boolean shouldTrackLocked() {
            final long nowElapsed = sElapsedRealtimeClock.millis();
            final int standbyBucket = JobSchedulerService.standbyBucketForPackage(mPkg.packageName,
@@ -2132,7 +2148,7 @@ public final class QuotaController extends StateController {
            final long topAppGracePeriodEndElapsed = mTopAppGraceCache.get(mUid);
            final boolean hasTopAppExemption = !mRegularJobTimer
                    && (mTopAppCache.get(mUid) || nowElapsed < topAppGracePeriodEndElapsed);
            return (standbyBucket == RESTRICTED_INDEX || !mChargeTracker.isCharging())
            return !isQuotaFreeLocked(standbyBucket)
                    && !mForegroundUids.get(mUid) && !hasTempAllowlistExemption
                    && !hasTopAppExemption;
        }
@@ -4054,7 +4070,7 @@ public final class QuotaController extends StateController {
    @Override
    public void dumpControllerStateLocked(final IndentingPrintWriter pw,
            final Predicate<JobStatus> predicate) {
        pw.println("Is charging: " + mChargeTracker.isCharging());
        pw.println("Is charging: " + mChargeTracker.isChargingLocked());
        pw.println("Current elapsed time: " + sElapsedRealtimeClock.millis());
        pw.println();

@@ -4231,7 +4247,8 @@ public final class QuotaController extends StateController {
        final long token = proto.start(fieldId);
        final long mToken = proto.start(StateControllerProto.QUOTA);

        proto.write(StateControllerProto.QuotaController.IS_CHARGING, mChargeTracker.isCharging());
        proto.write(StateControllerProto.QuotaController.IS_CHARGING,
                mChargeTracker.isChargingLocked());
        proto.write(StateControllerProto.QuotaController.ELAPSED_REALTIME,
                sElapsedRealtimeClock.millis());