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

Commit b4914523 authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

Log when job quota is reduced for buggy apps

Count the times job scheduler artificially lowers quota for a job
because it considers the caller buggy due to excessive job timeouts.

The logic is refactored to allow simpler logging, but no other
functional change is intended.

Test: statsd_testdrive 528

Existing job tests:
Test: atest FrameworksMockingServicesTests:JobSchedulerServiceTest
Test: atest FrameworksMockingServicesTests:JobStatusTest

Bug: 291146667
Change-Id: I62654be0a0cdc713a17146c3ec612b37e8283b3e
parent 4a12d7bd
Loading
Loading
Loading
Loading
+26 −8
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.modules.expresslog.Counter;
import com.android.server.LocalServices;
import com.android.server.job.GrantedUriPermissions;
import com.android.server.job.JobSchedulerInternal;
@@ -161,6 +162,9 @@ public final class JobStatus {
    /** If the job is going to be passed an unmetered network. */
    private boolean mHasAccessToUnmetered;

    /** If the effective bucket has been downgraded once due to being buggy. */
    private boolean mIsDowngradedDueToBuggyApp;

    /**
     * The additional set of dynamic constraints that must be met if this is an expedited job that
     * had a long enough run while the device was Dozing or in battery saver.
@@ -1173,18 +1177,32 @@ public final class JobStatus {
            // like other ACTIVE apps.
            return ACTIVE_INDEX;
        }

        final int bucketWithMediaExemption;
        if (actualBucket != RESTRICTED_INDEX && actualBucket != NEVER_INDEX
                && mHasMediaBackupExemption) {
            // Treat it as if it's at most WORKING_INDEX (lower index grants higher quota) since
            // media backup jobs are important to the user, and the source package may not have
            // been used directly in a while.
            bucketWithMediaExemption = Math.min(WORKING_INDEX, actualBucket);
        } else {
            bucketWithMediaExemption = actualBucket;
        }

        // If the app is considered buggy, but hasn't yet been put in the RESTRICTED bucket
        // (potentially because it's used frequently by the user), limit its effective bucket
        // so that it doesn't get to run as much as a normal ACTIVE app.
        final int highestBucket = isBuggy ? WORKING_INDEX : ACTIVE_INDEX;
        if (actualBucket != RESTRICTED_INDEX && actualBucket != NEVER_INDEX
                && mHasMediaBackupExemption) {
            // Treat it as if it's at least WORKING_INDEX since media backup jobs are important
            // to the user, and the
            // source package may not have been used directly in a while.
            return Math.max(highestBucket, Math.min(WORKING_INDEX, actualBucket));
        if (isBuggy && bucketWithMediaExemption < WORKING_INDEX) {
            if (!mIsDowngradedDueToBuggyApp) {
                // Safety check to avoid logging multiple times for the same job.
                Counter.logIncrementWithUid(
                        "job_scheduler.value_job_quota_reduced_due_to_buggy_uid",
                        getTimeoutBlameUid());
                mIsDowngradedDueToBuggyApp = true;
            }
            return WORKING_INDEX;
        }
        return Math.max(highestBucket, actualBucket);
        return bucketWithMediaExemption;
    }

    /** Returns the real standby bucket of the job. */